@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.
- package/CHANGELOG.md +345 -0
- package/README.md +45 -1402
- package/dist/actions/body/converters.d.ts +20 -0
- package/dist/actions/body/converters.js +57 -0
- package/dist/actions/body/converters.js.map +1 -0
- package/dist/actions/body/escapeHtml.d.ts +6 -0
- package/dist/actions/body/escapeHtml.js +14 -0
- package/dist/actions/body/escapeHtml.js.map +1 -0
- package/dist/actions/body/serializeBody.d.ts +55 -0
- package/dist/actions/body/serializeBody.js +78 -0
- package/dist/actions/body/serializeBody.js.map +1 -0
- package/dist/actions/body/serializeSlate.js +31 -0
- package/dist/actions/body/serializeSlate.js.map +1 -0
- package/dist/actions/body/textOfBody.d.ts +13 -0
- package/dist/actions/body/textOfBody.js +35 -0
- package/dist/actions/body/textOfBody.js.map +1 -0
- package/dist/actions/body/wildcards.d.ts +10 -0
- package/dist/actions/body/wildcards.js +33 -0
- package/dist/actions/body/wildcards.js.map +1 -0
- package/dist/actions/buildActionBlocks.js +22 -0
- package/dist/actions/buildActionBlocks.js.map +1 -0
- package/dist/actions/builtin/confirmation.js +52 -0
- package/dist/actions/builtin/confirmation.js.map +1 -0
- package/dist/actions/builtin/emailAction.d.ts +17 -0
- package/dist/actions/builtin/emailAction.js +83 -0
- package/dist/actions/builtin/emailAction.js.map +1 -0
- package/dist/actions/builtin/emailTeam.js +22 -0
- package/dist/actions/builtin/emailTeam.js.map +1 -0
- package/dist/actions/builtin/index.d.ts +22 -0
- package/dist/actions/builtin/index.js +27 -0
- package/dist/actions/builtin/index.js.map +1 -0
- package/dist/actions/builtin/signedWebhook.js +53 -0
- package/dist/actions/builtin/signedWebhook.js.map +1 -0
- package/dist/actions/defineAction.d.ts +37 -0
- package/dist/actions/defineAction.js +6 -0
- package/dist/actions/defineAction.js.map +1 -0
- package/dist/actions/dispatch.js +49 -0
- package/dist/actions/dispatch.js.map +1 -0
- package/dist/actions/emailRecipients.d.ts +12 -0
- package/dist/actions/emailRecipients.js +116 -0
- package/dist/actions/emailRecipients.js.map +1 -0
- package/dist/actions/fromAddresses.d.ts +21 -0
- package/dist/actions/fromAddresses.js +74 -0
- package/dist/actions/fromAddresses.js.map +1 -0
- package/dist/actions/registry.d.ts +17 -0
- package/dist/actions/registry.js +12 -0
- package/dist/actions/registry.js.map +1 -0
- package/dist/actions/runActions.d.ts +9 -0
- package/dist/actions/runActions.js +43 -0
- package/dist/actions/runActions.js.map +1 -0
- package/dist/actions/sign.d.ts +7 -0
- package/dist/actions/sign.js +9 -0
- package/dist/actions/sign.js.map +1 -0
- package/dist/actions/task.js +87 -0
- package/dist/actions/task.js.map +1 -0
- package/dist/aggregation/aggregateResponses.d.ts +40 -0
- package/dist/aggregation/aggregateResponses.js +80 -0
- package/dist/aggregation/aggregateResponses.js.map +1 -0
- package/dist/aggregation/aggregateRows.d.ts +10 -0
- package/dist/aggregation/aggregateRows.js +64 -0
- package/dist/aggregation/aggregateRows.js.map +1 -0
- package/dist/aggregation/resolveResultsRequest.d.ts +61 -0
- package/dist/aggregation/resolveResultsRequest.js +113 -0
- package/dist/aggregation/resolveResultsRequest.js.map +1 -0
- package/dist/aggregation/types.d.ts +39 -0
- package/dist/calc/computeCalcFields.d.ts +15 -0
- package/dist/calc/computeCalcFields.js +28 -0
- package/dist/calc/computeCalcFields.js.map +1 -0
- package/dist/calc/evaluate.d.ts +8 -0
- package/dist/calc/evaluate.js +58 -0
- package/dist/calc/evaluate.js.map +1 -0
- package/dist/calc/normalizeCalc.d.ts +8 -0
- package/dist/calc/normalizeCalc.js +87 -0
- package/dist/calc/normalizeCalc.js.map +1 -0
- package/dist/calc/types.d.ts +34 -0
- package/dist/calc/types.js +22 -0
- package/dist/calc/types.js.map +1 -0
- package/dist/client/ByteSizeField.d.ts +29 -0
- package/dist/client/ByteSizeField.js +58 -0
- package/dist/client/ByteSizeField.js.map +1 -0
- package/dist/client/ClosePollButton.d.ts +15 -0
- package/dist/client/ClosePollButton.js +80 -0
- package/dist/client/ClosePollButton.js.map +1 -0
- package/dist/client/CondensedArray.d.ts +15 -0
- package/dist/client/CondensedArray.js +97 -0
- package/dist/client/CondensedArray.js.map +1 -0
- package/dist/client/ConditionBuilder.js +122 -0
- package/dist/client/ConditionBuilder.js.map +1 -0
- package/dist/client/ConditionRow.js +150 -0
- package/dist/client/ConditionRow.js.map +1 -0
- package/dist/client/ConsentBlockLabel.d.ts +15 -0
- package/dist/client/ConsentBlockLabel.js +71 -0
- package/dist/client/ConsentBlockLabel.js.map +1 -0
- package/dist/client/ConsentSourceRowLabel.d.ts +9 -0
- package/dist/client/ConsentSourceRowLabel.js +21 -0
- package/dist/client/ConsentSourceRowLabel.js.map +1 -0
- package/dist/client/EndpointOptionsSelect.d.ts +46 -0
- package/dist/client/EndpointOptionsSelect.js +106 -0
- package/dist/client/EndpointOptionsSelect.js.map +1 -0
- package/dist/client/FieldBlockLabel.d.ts +18 -0
- package/dist/client/FieldBlockLabel.js +34 -0
- package/dist/client/FieldBlockLabel.js.map +1 -0
- package/dist/client/FieldNameSelect.d.ts +37 -0
- package/dist/client/FieldNameSelect.js +72 -0
- package/dist/client/FieldNameSelect.js.map +1 -0
- package/dist/client/FlowBuilder.d.ts +15 -0
- package/dist/client/FlowBuilder.js +457 -0
- package/dist/client/FlowBuilder.js.map +1 -0
- package/dist/client/FormConditionField.d.ts +21 -0
- package/dist/client/FormConditionField.js +30 -0
- package/dist/client/FormConditionField.js.map +1 -0
- package/dist/client/RecipientsSelect.d.ts +31 -0
- package/dist/client/RecipientsSelect.js +174 -0
- package/dist/client/RecipientsSelect.js.map +1 -0
- package/dist/client/RuleDescription.d.ts +21 -0
- package/dist/client/RuleDescription.js +19 -0
- package/dist/client/RuleDescription.js.map +1 -0
- package/dist/client/admin.css +275 -0
- package/dist/client/endpointOptions.js +29 -0
- package/dist/client/endpointOptions.js.map +1 -0
- package/dist/client/flowAuthoring.js +142 -0
- package/dist/client/flowAuthoring.js.map +1 -0
- package/dist/client/synthesizeClientField.js +57 -0
- package/dist/client/synthesizeClientField.js.map +1 -0
- package/dist/client/toStaticLabel.js +13 -0
- package/dist/client/toStaticLabel.js.map +1 -0
- package/dist/collections/buttonFields.d.ts +34 -0
- package/dist/collections/buttonFields.js +35 -0
- package/dist/collections/buttonFields.js.map +1 -0
- package/dist/collections/cells/FieldCountCell.d.ts +15 -0
- package/dist/collections/cells/FieldCountCell.js +18 -0
- package/dist/collections/cells/FieldCountCell.js.map +1 -0
- package/dist/collections/cells/FlowStepsCell.d.ts +14 -0
- package/dist/collections/cells/FlowStepsCell.js +17 -0
- package/dist/collections/cells/FlowStepsCell.js.map +1 -0
- package/dist/collections/formSubmissions.js +204 -0
- package/dist/collections/formSubmissions.js.map +1 -0
- package/dist/collections/forms.js +482 -0
- package/dist/collections/forms.js.map +1 -0
- package/dist/collections/formsEndpoints.js +101 -0
- package/dist/collections/formsEndpoints.js.map +1 -0
- package/dist/collections/redirectFields.d.ts +29 -0
- package/dist/conditions/conditionType.js +21 -0
- package/dist/conditions/conditionType.js.map +1 -0
- package/dist/conditions/evaluate.d.ts +17 -0
- package/dist/conditions/evaluate.js +94 -0
- package/dist/conditions/evaluate.js.map +1 -0
- package/dist/conditions/fieldTypes.d.ts +11 -0
- package/dist/{fieldTypes-CzhhJXjg.js → conditions/fieldTypes.js} +6 -3
- package/dist/conditions/fieldTypes.js.map +1 -0
- package/dist/conditions/normalizeConditions.js +61 -0
- package/dist/conditions/normalizeConditions.js.map +1 -0
- package/dist/conditions/types.d.ts +8 -0
- package/dist/consent/applyConsentStatements.d.ts +14 -0
- package/dist/consent/applyConsentStatements.js +17 -0
- package/dist/consent/applyConsentStatements.js.map +1 -0
- package/dist/consent/captureConsent.d.ts +55 -0
- package/dist/consent/captureConsent.js +73 -0
- package/dist/consent/captureConsent.js.map +1 -0
- package/dist/consent/consentSourcesField.d.ts +66 -0
- package/dist/consent/consentSourcesField.js +90 -0
- package/dist/consent/consentSourcesField.js.map +1 -0
- package/dist/consent/resolveConsentEntries.d.ts +24 -0
- package/dist/consent/resolveConsentEntries.js +40 -0
- package/dist/consent/resolveConsentEntries.js.map +1 -0
- package/dist/consent/resolveConsentSourcesRequest.d.ts +37 -0
- package/dist/consent/resolveConsentSourcesRequest.js +54 -0
- package/dist/consent/resolveConsentSourcesRequest.js.map +1 -0
- package/dist/consent/resolveConsentStatements.d.ts +45 -0
- package/dist/consent/resolveConsentStatements.js +44 -0
- package/dist/consent/resolveConsentStatements.js.map +1 -0
- package/dist/consent/resolvePublishedVersionRef.d.ts +23 -0
- package/dist/consent/resolvePublishedVersionRef.js +30 -0
- package/dist/consent/resolvePublishedVersionRef.js.map +1 -0
- package/dist/consent/types.d.ts +61 -0
- package/dist/email/departments.d.ts +59 -0
- package/dist/email/departments.js +87 -0
- package/dist/email/departments.js.map +1 -0
- package/dist/email/departmentsField.d.ts +53 -0
- package/dist/email/departmentsField.js +73 -0
- package/dist/email/departmentsField.js.map +1 -0
- package/dist/events/noopSink.js +6 -0
- package/dist/events/noopSink.js.map +1 -0
- package/dist/events/resolveEventSink.js +8 -0
- package/dist/events/resolveEventSink.js.map +1 -0
- package/dist/events/types.d.ts +31 -0
- package/dist/exports/client.d.ts +15 -21
- package/dist/exports/client.js +15 -319
- package/dist/exports/i18n.d.ts +6 -138
- package/dist/exports/i18n.js +6 -3
- package/dist/exports/react.d.ts +63 -550
- package/dist/exports/react.js +55 -1563
- package/dist/exports/rsc.d.ts +9 -16
- package/dist/exports/rsc.js +9 -55
- package/dist/exports/types.d.ts +36 -5
- package/dist/fields/buildFieldBlocks.js +80 -0
- package/dist/fields/buildFieldBlocks.js.map +1 -0
- package/dist/fields/builtin/calculation.js +144 -0
- package/dist/fields/builtin/calculation.js.map +1 -0
- package/dist/fields/builtin/checkbox.js +21 -0
- package/dist/fields/builtin/checkbox.js.map +1 -0
- package/dist/fields/builtin/consent.js +47 -0
- package/dist/fields/builtin/consent.js.map +1 -0
- package/dist/fields/builtin/country.d.ts +13 -0
- package/dist/fields/builtin/country.js +30 -0
- package/dist/fields/builtin/country.js.map +1 -0
- package/dist/fields/builtin/date.js +31 -0
- package/dist/fields/builtin/date.js.map +1 -0
- package/dist/fields/builtin/email.js +18 -0
- package/dist/fields/builtin/email.js.map +1 -0
- package/dist/fields/builtin/file.d.ts +15 -0
- package/dist/fields/builtin/file.js +127 -0
- package/dist/fields/builtin/file.js.map +1 -0
- package/dist/fields/builtin/index.d.ts +26 -0
- package/dist/fields/builtin/index.js +49 -0
- package/dist/fields/builtin/index.js.map +1 -0
- package/dist/fields/builtin/message.js +30 -0
- package/dist/fields/builtin/message.js.map +1 -0
- package/dist/fields/builtin/number.js +17 -0
- package/dist/fields/builtin/number.js.map +1 -0
- package/dist/fields/builtin/repeater.js +49 -0
- package/dist/fields/builtin/repeater.js.map +1 -0
- package/dist/fields/builtin/select.js +49 -0
- package/dist/fields/builtin/select.js.map +1 -0
- package/dist/fields/builtin/state.d.ts +13 -0
- package/dist/fields/builtin/state.js +30 -0
- package/dist/fields/builtin/state.js.map +1 -0
- package/dist/fields/builtin/text.js +13 -0
- package/dist/fields/builtin/text.js.map +1 -0
- package/dist/fields/builtin/textarea.js +13 -0
- package/dist/fields/builtin/textarea.js.map +1 -0
- package/dist/fields/data/regions.d.ts +21 -0
- package/dist/fields/data/regions.js +1238 -0
- package/dist/fields/data/regions.js.map +1 -0
- package/dist/fields/defineFormField.d.ts +13 -0
- package/dist/fields/defineFormField.js +12 -0
- package/dist/fields/defineFormField.js.map +1 -0
- package/dist/fields/fieldKey.d.ts +15 -0
- package/dist/fields/fieldKey.js +16 -0
- package/dist/fields/fieldKey.js.map +1 -0
- package/dist/fields/fieldNamesOfType.js +30 -0
- package/dist/fields/fieldNamesOfType.js.map +1 -0
- package/dist/fields/instanceOptions.js +20 -0
- package/dist/fields/instanceOptions.js.map +1 -0
- package/dist/fields/localizedIf.d.ts +13 -0
- package/dist/fields/localizedIf.js +12 -0
- package/dist/fields/localizedIf.js.map +1 -0
- package/dist/fields/registry.d.ts +12 -0
- package/dist/fields/registry.js +39 -0
- package/dist/fields/registry.js.map +1 -0
- package/dist/fields/sharedConfig.js +151 -0
- package/dist/fields/sharedConfig.js.map +1 -0
- package/dist/fields/types.d.ts +152 -0
- package/dist/flow/engine.d.ts +19 -0
- package/dist/flow/engine.js +29 -0
- package/dist/flow/engine.js.map +1 -0
- package/dist/flow/normalizeFlow.js +54 -0
- package/dist/flow/normalizeFlow.js.map +1 -0
- package/dist/flow/stepLabel.js +15 -0
- package/dist/flow/stepLabel.js.map +1 -0
- package/dist/flow/types.d.ts +32 -0
- package/dist/flow/types.js +11 -0
- package/dist/flow/types.js.map +1 -0
- package/dist/form/pollState.d.ts +22 -0
- package/dist/form/pollState.js +17 -0
- package/dist/form/pollState.js.map +1 -0
- package/dist/form/toFormDocument.d.ts +102 -0
- package/dist/form/toFormDocument.js +87 -0
- package/dist/form/toFormDocument.js.map +1 -0
- package/dist/form/types.d.ts +65 -0
- package/dist/index.d.ts +88 -4
- package/dist/index.js +111 -1898
- package/dist/index.js.map +1 -1
- package/dist/options.d.ts +229 -0
- package/dist/plugin/access.js +12 -0
- package/dist/plugin/access.js.map +1 -0
- package/dist/plugin/applyRegistryConfig.d.ts +11 -0
- package/dist/plugin/applyRegistryConfig.js +20 -0
- package/dist/plugin/applyRegistryConfig.js.map +1 -0
- package/dist/plugin/collectionOverrides.d.ts +22 -0
- package/dist/plugin/customState.js +26 -0
- package/dist/plugin/customState.js.map +1 -0
- package/dist/plugin/registerCollections.js +60 -0
- package/dist/plugin/registerCollections.js.map +1 -0
- package/dist/plugin/registerTranslations.js +19 -0
- package/dist/plugin/registerTranslations.js.map +1 -0
- package/dist/plugin/uploadsCollection.d.ts +16 -0
- package/dist/plugin/uploadsCollection.js +53 -0
- package/dist/plugin/uploadsCollection.js.map +1 -0
- package/dist/poll/applyPollOptions.js +18 -0
- package/dist/poll/applyPollOptions.js.map +1 -0
- package/dist/poll/buildPollOptionSourceFields.js +50 -0
- package/dist/poll/buildPollOptionSourceFields.js.map +1 -0
- package/dist/poll/closeJob.d.ts +52 -0
- package/dist/poll/closeJob.js +119 -0
- package/dist/poll/closeJob.js.map +1 -0
- package/dist/poll/definePollOptionSource.d.ts +44 -0
- package/dist/poll/definePollOptionSource.js +6 -0
- package/dist/poll/definePollOptionSource.js.map +1 -0
- package/dist/poll/definePollType.d.ts +34 -0
- package/dist/poll/definePollType.js +6 -0
- package/dist/poll/definePollType.js.map +1 -0
- package/dist/poll/effectivePollOptions.d.ts +38 -0
- package/dist/poll/effectivePollOptions.js +64 -0
- package/dist/poll/effectivePollOptions.js.map +1 -0
- package/dist/poll/mostVoted.d.ts +21 -0
- package/dist/poll/mostVoted.js +32 -0
- package/dist/poll/mostVoted.js.map +1 -0
- package/dist/poll/outcomeBeforeChange.js +91 -0
- package/dist/poll/outcomeBeforeChange.js.map +1 -0
- package/dist/poll/outcomeFields.d.ts +38 -0
- package/dist/poll/outcomeFields.js +52 -0
- package/dist/poll/outcomeFields.js.map +1 -0
- package/dist/poll/pollTypeRegistry.d.ts +34 -0
- package/dist/poll/pollTypeRegistry.js +69 -0
- package/dist/poll/pollTypeRegistry.js.map +1 -0
- package/dist/poll/registry.d.ts +17 -0
- package/dist/poll/registry.js +12 -0
- package/dist/poll/registry.js.map +1 -0
- package/dist/poll/resolvePollCloseRequest.js +105 -0
- package/dist/poll/resolvePollCloseRequest.js.map +1 -0
- package/dist/poll/resolvePollOptions.d.ts +29 -0
- package/dist/poll/resolvePollOptions.js +52 -0
- package/dist/poll/resolvePollOptions.js.map +1 -0
- package/dist/poll/resolvePollOptionsRequest.js +50 -0
- package/dist/poll/resolvePollOptionsRequest.js.map +1 -0
- package/dist/poll/resolvePollOutcome.d.ts +34 -0
- package/dist/poll/resolvePollOutcome.js +76 -0
- package/dist/poll/resolvePollOutcome.js.map +1 -0
- package/dist/poll/resultsField.js +21 -0
- package/dist/poll/resultsField.js.map +1 -0
- package/dist/prefill/valuesFromSearchParams.d.ts +18 -0
- package/dist/prefill/valuesFromSearchParams.js +41 -0
- package/dist/prefill/valuesFromSearchParams.js.map +1 -0
- package/dist/presentations/defaults.d.ts +33 -0
- package/dist/presentations/defaults.js +35 -0
- package/dist/presentations/defaults.js.map +1 -0
- package/dist/presentations/types.d.ts +19 -0
- package/dist/react/Form.d.ts +128 -0
- package/dist/react/Form.js +619 -0
- package/dist/react/Form.js.map +1 -0
- package/dist/react/FormContext.d.ts +59 -0
- package/dist/react/FormContext.js +14 -0
- package/dist/react/FormContext.js.map +1 -0
- package/dist/react/FormControls.d.ts +55 -0
- package/dist/react/FormControls.js +56 -0
- package/dist/react/FormControls.js.map +1 -0
- package/dist/react/FormFields.d.ts +18 -0
- package/dist/react/FormFields.js +114 -0
- package/dist/react/FormFields.js.map +1 -0
- package/dist/react/FormLayout.d.ts +22 -0
- package/dist/react/FormLayout.js +15 -0
- package/dist/react/FormLayout.js.map +1 -0
- package/dist/react/FormResults.d.ts +28 -0
- package/dist/react/FormResults.js +93 -0
- package/dist/react/FormResults.js.map +1 -0
- package/dist/react/FormSteps.d.ts +17 -0
- package/dist/react/FormSteps.js +35 -0
- package/dist/react/FormSteps.js.map +1 -0
- package/dist/react/Honeypot.d.ts +22 -0
- package/dist/react/Honeypot.js +38 -0
- package/dist/react/Honeypot.js.map +1 -0
- package/dist/react/Poll.d.ts +43 -0
- package/dist/react/Poll.js +135 -0
- package/dist/react/Poll.js.map +1 -0
- package/dist/react/captcha/HcaptchaCaptcha.d.ts +28 -0
- package/dist/react/captcha/HcaptchaCaptcha.js +53 -0
- package/dist/react/captcha/HcaptchaCaptcha.js.map +1 -0
- package/dist/react/captcha/RecaptchaCaptcha.d.ts +41 -0
- package/dist/react/captcha/RecaptchaCaptcha.js +93 -0
- package/dist/react/captcha/RecaptchaCaptcha.js.map +1 -0
- package/dist/react/captcha/TurnstileCaptcha.d.ts +28 -0
- package/dist/react/captcha/TurnstileCaptcha.js +53 -0
- package/dist/react/captcha/TurnstileCaptcha.js.map +1 -0
- package/dist/react/captcha/types.d.ts +8 -0
- package/dist/react/captcha/useCaptchaScript.js +45 -0
- package/dist/react/captcha/useCaptchaScript.js.map +1 -0
- package/dist/react/captcha/vendors.js +8 -0
- package/dist/react/captcha/vendors.js.map +1 -0
- package/dist/react/cn.d.ts +6 -0
- package/dist/react/cn.js +8 -0
- package/dist/react/cn.js.map +1 -0
- package/dist/react/contract.d.ts +31 -0
- package/dist/react/contract.js +7 -0
- package/dist/react/contract.js.map +1 -0
- package/dist/react/events.js +14 -0
- package/dist/react/events.js.map +1 -0
- package/dist/react/fetchResults.d.ts +25 -0
- package/dist/react/fetchResults.js +31 -0
- package/dist/react/fetchResults.js.map +1 -0
- package/dist/react/presentation/Backdrop.d.ts +18 -0
- package/dist/react/presentation/Backdrop.js +14 -0
- package/dist/react/presentation/Backdrop.js.map +1 -0
- package/dist/react/presentation/DialogSurface.d.ts +35 -0
- package/dist/react/presentation/DialogSurface.js +53 -0
- package/dist/react/presentation/DialogSurface.js.map +1 -0
- package/dist/react/presentation/presentations.d.ts +7 -0
- package/dist/react/presentation/presentations.js +32 -0
- package/dist/react/presentation/presentations.js.map +1 -0
- package/dist/react/presentation/registry.d.ts +11 -0
- package/dist/react/presentation/registry.js +12 -0
- package/dist/react/presentation/registry.js.map +1 -0
- package/dist/react/presentation/types.d.ts +19 -0
- package/dist/react/presentation/useDismiss.d.ts +19 -0
- package/dist/react/presentation/useDismiss.js +33 -0
- package/dist/react/presentation/useDismiss.js.map +1 -0
- package/dist/react/presentation/useFocusTrap.d.ts +8 -0
- package/dist/react/presentation/useFocusTrap.js +35 -0
- package/dist/react/presentation/useFocusTrap.js.map +1 -0
- package/dist/react/presentation/useScrollLock.d.ts +6 -0
- package/dist/react/presentation/useScrollLock.js +18 -0
- package/dist/react/presentation/useScrollLock.js.map +1 -0
- package/dist/react/primitives/Checkbox.d.ts +28 -0
- package/dist/react/primitives/Checkbox.js +21 -0
- package/dist/react/primitives/Checkbox.js.map +1 -0
- package/dist/react/primitives/FieldShell.d.ts +29 -0
- package/dist/react/primitives/FieldShell.js +44 -0
- package/dist/react/primitives/FieldShell.js.map +1 -0
- package/dist/react/primitives/Input.d.ts +30 -0
- package/dist/react/primitives/Input.js +21 -0
- package/dist/react/primitives/Input.js.map +1 -0
- package/dist/react/primitives/Select.d.ts +34 -0
- package/dist/react/primitives/Select.js +26 -0
- package/dist/react/primitives/Select.js.map +1 -0
- package/dist/react/primitives/Textarea.d.ts +28 -0
- package/dist/react/primitives/Textarea.js +20 -0
- package/dist/react/primitives/Textarea.js.map +1 -0
- package/dist/react/recall.js +20 -0
- package/dist/react/recall.js.map +1 -0
- package/dist/react/registry.d.ts +16 -0
- package/dist/react/registry.js +16 -0
- package/dist/react/registry.js.map +1 -0
- package/dist/react/renderers/calculation.js +27 -0
- package/dist/react/renderers/calculation.js.map +1 -0
- package/dist/react/renderers/checkbox.js +32 -0
- package/dist/react/renderers/checkbox.js.map +1 -0
- package/dist/react/renderers/consent.js +97 -0
- package/dist/react/renderers/consent.js.map +1 -0
- package/dist/react/renderers/date.js +33 -0
- package/dist/react/renderers/date.js.map +1 -0
- package/dist/react/renderers/email.js +34 -0
- package/dist/react/renderers/email.js.map +1 -0
- package/dist/react/renderers/file.js +107 -0
- package/dist/react/renderers/file.js.map +1 -0
- package/dist/react/renderers/index.d.ts +8 -0
- package/dist/react/renderers/index.js +35 -0
- package/dist/react/renderers/index.js.map +1 -0
- package/dist/react/renderers/message.js +41 -0
- package/dist/react/renderers/message.js.map +1 -0
- package/dist/react/renderers/number.js +37 -0
- package/dist/react/renderers/number.js.map +1 -0
- package/dist/react/renderers/region.js +43 -0
- package/dist/react/renderers/region.js.map +1 -0
- package/dist/react/renderers/repeater.js +131 -0
- package/dist/react/renderers/repeater.js.map +1 -0
- package/dist/react/renderers/select.js +35 -0
- package/dist/react/renderers/select.js.map +1 -0
- package/dist/react/renderers/text.js +34 -0
- package/dist/react/renderers/text.js.map +1 -0
- package/dist/react/renderers/textarea.js +33 -0
- package/dist/react/renderers/textarea.js.map +1 -0
- package/dist/react/resolveForm.js +16 -0
- package/dist/react/resolveForm.js.map +1 -0
- package/dist/react/state.d.ts +52 -0
- package/dist/react/state.js +125 -0
- package/dist/react/state.js.map +1 -0
- package/dist/react/submitForm.d.ts +31 -0
- package/dist/react/submitForm.js +58 -0
- package/dist/react/submitForm.js.map +1 -0
- package/dist/react/uploadFile.d.ts +23 -0
- package/dist/react/uploadFile.js +39 -0
- package/dist/react/uploadFile.js.map +1 -0
- package/dist/react/useField.d.ts +13 -0
- package/dist/react/useField.js +49 -0
- package/dist/react/useField.js.map +1 -0
- package/dist/react/useFormState.d.ts +8 -0
- package/dist/react/useFormState.js +9 -0
- package/dist/react/useFormState.js.map +1 -0
- package/dist/react/useFormStep.d.ts +8 -0
- package/dist/react/useFormStep.js +9 -0
- package/dist/react/useFormStep.js.map +1 -0
- package/dist/react/validateField.js +27 -0
- package/dist/react/validateField.js.map +1 -0
- package/dist/recall/interpolate.d.ts +11 -0
- package/dist/recall/interpolate.js +17 -0
- package/dist/recall/interpolate.js.map +1 -0
- package/dist/recall/resolver.d.ts +22 -0
- package/dist/recall/resolver.js +48 -0
- package/dist/recall/resolver.js.map +1 -0
- package/dist/spam/captcha.d.ts +13 -0
- package/dist/spam/captcha.js +12 -0
- package/dist/spam/captcha.js.map +1 -0
- package/dist/spam/clientIp.js +9 -0
- package/dist/spam/clientIp.js.map +1 -0
- package/dist/spam/constants.d.ts +12 -0
- package/dist/spam/constants.js +21 -0
- package/dist/spam/constants.js.map +1 -0
- package/dist/spam/identify.d.ts +12 -0
- package/dist/spam/identify.js +17 -0
- package/dist/spam/identify.js.map +1 -0
- package/dist/spam/providers/hcaptcha.d.ts +17 -0
- package/dist/spam/providers/hcaptcha.js +18 -0
- package/dist/spam/providers/hcaptcha.js.map +1 -0
- package/dist/spam/providers/recaptcha.d.ts +23 -0
- package/dist/spam/providers/recaptcha.js +23 -0
- package/dist/spam/providers/recaptcha.js.map +1 -0
- package/dist/spam/providers/siteverify.js +34 -0
- package/dist/spam/providers/siteverify.js.map +1 -0
- package/dist/spam/providers/turnstile.d.ts +17 -0
- package/dist/spam/providers/turnstile.js +18 -0
- package/dist/spam/providers/turnstile.js.map +1 -0
- package/dist/spam/rateLimiter.d.ts +18 -0
- package/dist/spam/rateLimiter.js +41 -0
- package/dist/spam/rateLimiter.js.map +1 -0
- package/dist/spam/reserved.js +30 -0
- package/dist/spam/reserved.js.map +1 -0
- package/dist/spam/resolveSpam.d.ts +12 -0
- package/dist/spam/resolveSpam.js +43 -0
- package/dist/spam/resolveSpam.js.map +1 -0
- package/dist/spam/spamGuard.js +81 -0
- package/dist/spam/spamGuard.js.map +1 -0
- package/dist/spam/types.d.ts +88 -0
- package/dist/spam/uploadHooks.js +33 -0
- package/dist/spam/uploadHooks.js.map +1 -0
- package/dist/submissions/SubmissionAnswers.d.ts +14 -0
- package/dist/submissions/SubmissionAnswers.js +137 -0
- package/dist/submissions/SubmissionAnswers.js.map +1 -0
- package/dist/submissions/SubmissionAnswersClient.js +178 -0
- package/dist/submissions/SubmissionAnswersClient.js.map +1 -0
- package/dist/submissions/coerceBoolean.js +14 -0
- package/dist/submissions/coerceBoolean.js.map +1 -0
- package/dist/submissions/createSubmission.d.ts +36 -0
- package/dist/submissions/createSubmission.js +26 -0
- package/dist/submissions/createSubmission.js.map +1 -0
- package/dist/submissions/runSubmission.d.ts +10 -0
- package/dist/submissions/runSubmission.js +306 -0
- package/dist/submissions/runSubmission.js.map +1 -0
- package/dist/submissions/types.d.ts +41 -0
- package/dist/submissions/validateSubmission.js +110 -0
- package/dist/submissions/validateSubmission.js.map +1 -0
- package/dist/submissions/votedCookie.d.ts +13 -0
- package/dist/submissions/votedCookie.js +27 -0
- package/dist/submissions/votedCookie.js.map +1 -0
- package/dist/translations/clientRuntimeKeys.d.ts +17 -0
- package/dist/translations/clientRuntimeKeys.js +46 -0
- package/dist/translations/clientRuntimeKeys.js.map +1 -0
- package/dist/translations/de.d.ts +12 -0
- package/dist/translations/de.js +309 -0
- package/dist/translations/de.js.map +1 -0
- package/dist/translations/en.d.ts +12 -0
- package/dist/translations/en.js +309 -0
- package/dist/translations/en.js.map +1 -0
- package/dist/translations/index.d.ts +23 -0
- package/dist/translations/index.js +37 -0
- package/dist/translations/index.js.map +1 -0
- package/dist/translations/keys.d.ts +308 -0
- package/dist/translations/keys.js +308 -0
- package/dist/translations/keys.js.map +1 -0
- package/dist/translations/makeTranslate.d.ts +15 -0
- package/dist/translations/makeTranslate.js +20 -0
- package/dist/translations/makeTranslate.js.map +1 -0
- package/dist/translations/server.js +32 -0
- package/dist/translations/server.js.map +1 -0
- package/dist/translations/useTranslation.js +12 -0
- package/dist/translations/useTranslation.js.map +1 -0
- package/dist/uploads/captureFileRef.d.ts +34 -0
- package/dist/uploads/captureFileRef.js +43 -0
- package/dist/uploads/captureFileRef.js.map +1 -0
- package/dist/uploads/formatBytes.d.ts +9 -0
- package/dist/uploads/formatBytes.js +25 -0
- package/dist/uploads/formatBytes.js.map +1 -0
- package/dist/uploads/resolveFileRef.d.ts +26 -0
- package/dist/uploads/resolveFileRef.js +45 -0
- package/dist/uploads/resolveFileRef.js.map +1 -0
- package/dist/uploads/types.d.ts +19 -0
- package/dist/validation/buildRuleBlocks.js +47 -0
- package/dist/validation/buildRuleBlocks.js.map +1 -0
- package/dist/validation/builtin/email.js +20 -0
- package/dist/validation/builtin/email.js.map +1 -0
- package/dist/validation/builtin/index.d.ts +14 -0
- package/dist/validation/builtin/index.js +38 -0
- package/dist/validation/builtin/index.js.map +1 -0
- package/dist/validation/builtin/matchesField.js +16 -0
- package/dist/validation/builtin/matchesField.js.map +1 -0
- package/dist/validation/builtin/max.js +22 -0
- package/dist/validation/builtin/max.js.map +1 -0
- package/dist/validation/builtin/maxDate.js +24 -0
- package/dist/validation/builtin/maxDate.js.map +1 -0
- package/dist/validation/builtin/maxLength.js +27 -0
- package/dist/validation/builtin/maxLength.js.map +1 -0
- package/dist/validation/builtin/min.js +22 -0
- package/dist/validation/builtin/min.js.map +1 -0
- package/dist/validation/builtin/minDate.js +24 -0
- package/dist/validation/builtin/minDate.js.map +1 -0
- package/dist/validation/builtin/minLength.js +27 -0
- package/dist/validation/builtin/minLength.js.map +1 -0
- package/dist/validation/builtin/notAlreadySubmitted.js +34 -0
- package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -0
- package/dist/validation/builtin/oneOf.js +35 -0
- package/dist/validation/builtin/oneOf.js.map +1 -0
- package/dist/validation/builtin/pattern.js +50 -0
- package/dist/validation/builtin/pattern.js.map +1 -0
- package/dist/validation/builtin/url.js +23 -0
- package/dist/validation/builtin/url.js.map +1 -0
- package/dist/validation/builtin/validateDateBound.js +18 -0
- package/dist/validation/builtin/validateDateBound.js.map +1 -0
- package/dist/validation/builtin/validateRegexParams.js +44 -0
- package/dist/validation/builtin/validateRegexParams.js.map +1 -0
- package/dist/validation/defineValidationRule.d.ts +12 -0
- package/dist/validation/defineValidationRule.js +11 -0
- package/dist/validation/defineValidationRule.js.map +1 -0
- package/dist/validation/emailPattern.js +10 -0
- package/dist/validation/emailPattern.js.map +1 -0
- package/dist/validation/fieldTargetParam.d.ts +22 -0
- package/dist/validation/fieldTargetParam.js +38 -0
- package/dist/validation/fieldTargetParam.js.map +1 -0
- package/dist/validation/message.js +14 -0
- package/dist/validation/message.js.map +1 -0
- package/dist/validation/registry.d.ts +11 -0
- package/dist/validation/registry.js +13 -0
- package/dist/validation/registry.js.map +1 -0
- package/dist/validation/runValidation.js +90 -0
- package/dist/validation/runValidation.js.map +1 -0
- package/dist/validation/types.d.ts +70 -0
- package/dist/validation/validateUrl.js +22 -0
- package/dist/validation/validateUrl.js.map +1 -0
- package/package.json +12 -7
- package/styles/form-builder.css +21 -11
- package/dist/constants-B-BUfetP.d.ts +0 -288
- package/dist/exports/client.js.map +0 -1
- package/dist/exports/react.js.map +0 -1
- package/dist/exports/rsc.js.map +0 -1
- package/dist/fieldTypes-B8jkNRob.d.ts +0 -188
- package/dist/fieldTypes-CzhhJXjg.js.map +0 -1
- package/dist/index-DfFYGbVF.d.ts +0 -481
- package/dist/keys-N5xGiUsh.js +0 -132
- package/dist/keys-N5xGiUsh.js.map +0 -1
- package/dist/registry-CoCyhtvB.js +0 -282
- package/dist/registry-CoCyhtvB.js.map +0 -1
- package/dist/resolver-OeQyVH2N.js +0 -665
- package/dist/resolver-OeQyVH2N.js.map +0 -1
- package/dist/translations-edMqq_2e.js +0 -152
- package/dist/translations-edMqq_2e.js.map +0 -1
- 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
|