@10x-media/form-builder 0.1.0-beta.0 → 0.1.0-beta.1
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 +52 -0
- package/README.md +43 -1402
- package/dist/actions/buildActionBlocks.js +19 -0
- package/dist/actions/buildActionBlocks.js.map +1 -0
- package/dist/actions/builtin/confirmation.js +49 -0
- package/dist/actions/builtin/confirmation.js.map +1 -0
- package/dist/actions/builtin/emailTeam.js +46 -0
- package/dist/actions/builtin/emailTeam.js.map +1 -0
- package/dist/actions/builtin/index.d.ts +7 -0
- package/dist/actions/builtin/index.js +13 -0
- package/dist/actions/builtin/index.js.map +1 -0
- package/dist/actions/builtin/signedWebhook.js +49 -0
- package/dist/actions/builtin/signedWebhook.js.map +1 -0
- package/dist/actions/defineAction.d.ts +36 -0
- package/dist/actions/defineAction.js +6 -0
- package/dist/actions/defineAction.js.map +1 -0
- package/dist/actions/dispatch.js +48 -0
- package/dist/actions/dispatch.js.map +1 -0
- package/dist/actions/registry.d.ts +16 -0
- package/dist/actions/registry.js +16 -0
- package/dist/actions/registry.js.map +1 -0
- package/dist/actions/runActions.d.ts +9 -0
- package/dist/actions/runActions.js +34 -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 +82 -0
- package/dist/actions/task.js.map +1 -0
- package/dist/aggregation/aggregateResponses.d.ts +31 -0
- package/dist/aggregation/aggregateResponses.js +86 -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 +32 -0
- package/dist/aggregation/resolveResultsRequest.js +56 -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 +27 -0
- package/dist/calc/computeCalcFields.js.map +1 -0
- package/dist/calc/evaluate.d.ts +8 -0
- package/dist/calc/evaluate.js +59 -0
- package/dist/calc/evaluate.js.map +1 -0
- package/dist/calc/normalizeCalc.d.ts +8 -0
- package/dist/calc/normalizeCalc.js +100 -0
- package/dist/calc/normalizeCalc.js.map +1 -0
- package/dist/calc/types.d.ts +28 -0
- package/dist/client/ConditionBuilder.js +121 -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/FlowBuilder.d.ts +15 -0
- package/dist/client/FlowBuilder.js +408 -0
- package/dist/client/FlowBuilder.js.map +1 -0
- package/dist/client/FormConditionField.d.ts +21 -0
- package/dist/client/FormConditionField.js +33 -0
- package/dist/client/FormConditionField.js.map +1 -0
- package/dist/client/synthesizeClientField.js +46 -0
- package/dist/client/synthesizeClientField.js.map +1 -0
- package/dist/collections/formSubmissions.js +138 -0
- package/dist/collections/formSubmissions.js.map +1 -0
- package/dist/collections/forms.js +187 -0
- package/dist/collections/forms.js.map +1 -0
- package/dist/collections/uploads.d.ts +29 -0
- package/dist/collections/uploads.js +46 -0
- package/dist/collections/uploads.js.map +1 -0
- package/dist/conditions/conditionType.js +14 -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 +9 -0
- package/dist/{fieldTypes-CzhhJXjg.js → conditions/fieldTypes.js} +2 -2
- package/dist/conditions/fieldTypes.js.map +1 -0
- package/dist/conditions/normalizeConditions.js +47 -0
- package/dist/conditions/normalizeConditions.js.map +1 -0
- package/dist/conditions/types.d.ts +8 -0
- package/dist/consent/buildConsentSourceConfig.js +49 -0
- package/dist/consent/buildConsentSourceConfig.js.map +1 -0
- package/dist/consent/builtin/index.d.ts +7 -0
- package/dist/consent/builtin/index.js +11 -0
- package/dist/consent/builtin/index.js.map +1 -0
- package/dist/consent/builtin/pageReference.js +75 -0
- package/dist/consent/builtin/pageReference.js.map +1 -0
- package/dist/consent/builtin/static.js +44 -0
- package/dist/consent/builtin/static.js.map +1 -0
- package/dist/consent/captureConsent.d.ts +28 -0
- package/dist/consent/captureConsent.js +26 -0
- package/dist/consent/captureConsent.js.map +1 -0
- package/dist/consent/defineConsentSource.d.ts +35 -0
- package/dist/consent/defineConsentSource.js +6 -0
- package/dist/consent/defineConsentSource.js.map +1 -0
- package/dist/consent/registry.d.ts +16 -0
- package/dist/consent/registry.js +16 -0
- package/dist/consent/registry.js.map +1 -0
- package/dist/consent/resolveConsentLinks.d.ts +19 -0
- package/dist/consent/resolveConsentLinks.js +26 -0
- package/dist/consent/resolveConsentLinks.js.map +1 -0
- package/dist/consent/resolvePublishedVersionRef.d.ts +17 -0
- package/dist/consent/resolvePublishedVersionRef.js +27 -0
- package/dist/consent/resolvePublishedVersionRef.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 +3 -21
- package/dist/exports/client.js +3 -319
- package/dist/exports/i18n.d.ts +3 -138
- package/dist/exports/i18n.js +2 -2
- package/dist/exports/react.d.ts +45 -550
- package/dist/exports/react.js +39 -1563
- package/dist/exports/rsc.d.ts +2 -16
- package/dist/exports/rsc.js +1 -54
- package/dist/exports/types.d.ts +27 -5
- package/dist/fields/buildFieldBlocks.js +46 -0
- package/dist/fields/buildFieldBlocks.js.map +1 -0
- package/dist/fields/builtin/calculation.js +24 -0
- package/dist/fields/builtin/calculation.js.map +1 -0
- package/dist/fields/builtin/checkbox.js +13 -0
- package/dist/fields/builtin/checkbox.js.map +1 -0
- package/dist/fields/builtin/consent.js +32 -0
- package/dist/fields/builtin/consent.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.js +40 -0
- package/dist/fields/builtin/file.js.map +1 -0
- package/dist/fields/builtin/index.js +25 -0
- package/dist/fields/builtin/index.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/select.js +44 -0
- package/dist/fields/builtin/select.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/defineFormField.d.ts +13 -0
- package/dist/fields/defineFormField.js +12 -0
- package/dist/fields/defineFormField.js.map +1 -0
- package/dist/fields/registry.d.ts +10 -0
- package/dist/fields/registry.js +24 -0
- package/dist/fields/registry.js.map +1 -0
- package/dist/fields/sharedConfig.js +89 -0
- package/dist/fields/sharedConfig.js.map +1 -0
- package/dist/fields/types.d.ts +88 -0
- package/dist/flow/engine.d.ts +17 -0
- package/dist/flow/engine.js +24 -0
- package/dist/flow/engine.js.map +1 -0
- package/dist/flow/normalizeFlow.js +35 -0
- package/dist/flow/normalizeFlow.js.map +1 -0
- package/dist/{types-DsJ_6kGJ.d.ts → flow/types.d.ts} +2 -2
- package/dist/index.d.ts +74 -4
- package/dist/index.js +40 -1889
- package/dist/index.js.map +1 -1
- package/dist/plugin/access.js +12 -0
- package/dist/plugin/access.js.map +1 -0
- package/dist/plugin/registerCollections.js +40 -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/prefill/valuesFromSearchParams.d.ts +18 -0
- package/dist/prefill/valuesFromSearchParams.js +45 -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/registry.d.ts +15 -0
- package/dist/presentations/registry.js +15 -0
- package/dist/presentations/registry.js.map +1 -0
- package/dist/presentations/types.d.ts +18 -0
- package/dist/react/Form.d.ts +81 -0
- package/dist/react/Form.js +457 -0
- package/dist/react/Form.js.map +1 -0
- package/dist/react/FormContext.d.ts +16 -0
- package/dist/react/FormContext.js +14 -0
- package/dist/react/FormContext.js.map +1 -0
- package/dist/react/FormLayout.d.ts +20 -0
- package/dist/react/FormLayout.js +14 -0
- package/dist/react/FormLayout.js.map +1 -0
- package/dist/react/FormResults.d.ts +25 -0
- package/dist/react/FormResults.js +85 -0
- package/dist/react/FormResults.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 +32 -0
- package/dist/react/Poll.js +77 -0
- package/dist/react/Poll.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 +32 -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 +56 -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 +26 -0
- package/dist/react/primitives/Checkbox.js +20 -0
- package/dist/react/primitives/Checkbox.js.map +1 -0
- package/dist/react/primitives/FieldShell.d.ts +31 -0
- package/dist/react/primitives/FieldShell.js +51 -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 +30 -0
- package/dist/react/renderers/calculation.js.map +1 -0
- package/dist/react/renderers/checkbox.js +35 -0
- package/dist/react/renderers/checkbox.js.map +1 -0
- package/dist/react/renderers/consent.js +54 -0
- package/dist/react/renderers/consent.js.map +1 -0
- package/dist/react/renderers/email.js +37 -0
- package/dist/react/renderers/email.js.map +1 -0
- package/dist/react/renderers/file.js +92 -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 +26 -0
- package/dist/react/renderers/index.js.map +1 -0
- package/dist/react/renderers/number.js +40 -0
- package/dist/react/renderers/number.js.map +1 -0
- package/dist/react/renderers/select.js +38 -0
- package/dist/react/renderers/select.js.map +1 -0
- package/dist/react/renderers/text.js +37 -0
- package/dist/react/renderers/text.js.map +1 -0
- package/dist/react/renderers/textarea.js +36 -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 +15 -0
- package/dist/react/state.js +70 -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/toFormDocument.d.ts +24 -0
- package/dist/react/toFormDocument.js +22 -0
- package/dist/react/toFormDocument.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 +14 -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 +30 -0
- package/dist/react/validateField.js.map +1 -0
- package/dist/recall/interpolate.d.ts +10 -0
- package/dist/recall/interpolate.js +16 -0
- package/dist/recall/interpolate.js.map +1 -0
- package/dist/recall/resolver.d.ts +22 -0
- package/dist/recall/resolver.js +36 -0
- package/dist/recall/resolver.js.map +1 -0
- package/dist/spam/captcha.d.ts +12 -0
- package/dist/spam/captcha.js +11 -0
- package/dist/spam/captcha.js.map +1 -0
- package/dist/spam/constants.d.ts +12 -0
- package/dist/spam/constants.js +15 -0
- package/dist/spam/constants.js.map +1 -0
- package/dist/spam/identify.d.ts +12 -0
- package/dist/spam/identify.js +20 -0
- package/dist/spam/identify.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 +42 -0
- package/dist/spam/resolveSpam.js.map +1 -0
- package/dist/spam/spamGuard.js +68 -0
- package/dist/spam/spamGuard.js.map +1 -0
- package/dist/spam/types.d.ts +73 -0
- package/dist/spam/uploadHooks.js +33 -0
- package/dist/spam/uploadHooks.js.map +1 -0
- package/dist/submissions/SubmissionAnswers.d.ts +16 -0
- package/dist/submissions/SubmissionAnswers.js +57 -0
- package/dist/submissions/SubmissionAnswers.js.map +1 -0
- package/dist/submissions/runSubmission.js +205 -0
- package/dist/submissions/runSubmission.js.map +1 -0
- package/dist/submissions/types.d.ts +33 -0
- package/dist/submissions/validateSubmission.js +59 -0
- package/dist/submissions/validateSubmission.js.map +1 -0
- package/dist/translations/en.d.ts +12 -0
- package/dist/{translations-edMqq_2e.js → translations/en.js} +3 -22
- package/dist/translations/en.js.map +1 -0
- package/dist/translations/index.d.ts +14 -0
- package/dist/translations/index.js +26 -0
- package/dist/translations/index.js.map +1 -0
- package/dist/translations/keys.d.ts +132 -0
- package/dist/{keys-N5xGiUsh.js → translations/keys.js} +2 -2
- package/dist/translations/keys.js.map +1 -0
- package/dist/translations/makeTranslate.d.ts +11 -0
- package/dist/translations/makeTranslate.js +11 -0
- package/dist/translations/makeTranslate.js.map +1 -0
- package/dist/translations/server.js +25 -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 +27 -0
- package/dist/uploads/captureFileRef.js +34 -0
- package/dist/uploads/captureFileRef.js.map +1 -0
- package/dist/uploads/resolveFileRef.d.ts +26 -0
- package/dist/uploads/resolveFileRef.js +44 -0
- package/dist/uploads/resolveFileRef.js.map +1 -0
- package/dist/uploads/types.d.ts +20 -0
- package/dist/validation/buildRuleBlocks.js +46 -0
- package/dist/validation/buildRuleBlocks.js.map +1 -0
- package/dist/validation/builtin/email.js +19 -0
- package/dist/validation/builtin/email.js.map +1 -0
- package/dist/validation/builtin/index.js +27 -0
- package/dist/validation/builtin/index.js.map +1 -0
- package/dist/validation/builtin/matchesField.js +20 -0
- package/dist/validation/builtin/matchesField.js.map +1 -0
- package/dist/validation/builtin/max.js +21 -0
- package/dist/validation/builtin/max.js.map +1 -0
- package/dist/validation/builtin/maxLength.js +26 -0
- package/dist/validation/builtin/maxLength.js.map +1 -0
- package/dist/validation/builtin/min.js +21 -0
- package/dist/validation/builtin/min.js.map +1 -0
- package/dist/validation/builtin/minLength.js +26 -0
- package/dist/validation/builtin/minLength.js.map +1 -0
- package/dist/validation/builtin/notAlreadySubmitted.js +32 -0
- package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -0
- package/dist/validation/builtin/oneOf.js +34 -0
- package/dist/validation/builtin/oneOf.js.map +1 -0
- package/dist/validation/builtin/pattern.js +41 -0
- package/dist/validation/builtin/pattern.js.map +1 -0
- package/dist/validation/builtin/url.js +22 -0
- package/dist/validation/builtin/url.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/message.js +14 -0
- package/dist/validation/message.js.map +1 -0
- package/dist/validation/registry.d.ts +10 -0
- package/dist/validation/registry.js +20 -0
- package/dist/validation/registry.js.map +1 -0
- package/dist/validation/runValidation.js +111 -0
- package/dist/validation/runValidation.js.map +1 -0
- package/dist/validation/types.d.ts +76 -0
- package/package.json +8 -5
- package/styles/form-builder.css +201 -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.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.map +0 -1
|
@@ -0,0 +1,36 @@
|
|
|
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 { useId } from "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
//#region src/react/renderers/textarea.tsx
|
|
8
|
+
const textareaRenderer = defineFieldRenderer(({ field, name, value, onChange, onBlur, errors, warnings, required, disabled }) => {
|
|
9
|
+
const id = useId();
|
|
10
|
+
const describedById = `${id}-desc`;
|
|
11
|
+
return /* @__PURE__ */ jsx(FieldShell, {
|
|
12
|
+
id,
|
|
13
|
+
label: field.label,
|
|
14
|
+
description: typeof field.description === "string" ? field.description : void 0,
|
|
15
|
+
required,
|
|
16
|
+
errors,
|
|
17
|
+
warnings,
|
|
18
|
+
describedById,
|
|
19
|
+
children: /* @__PURE__ */ jsx(Textarea, {
|
|
20
|
+
id,
|
|
21
|
+
name,
|
|
22
|
+
value: value ?? "",
|
|
23
|
+
onChange,
|
|
24
|
+
onBlur,
|
|
25
|
+
placeholder: typeof field.placeholder === "string" ? field.placeholder : void 0,
|
|
26
|
+
required,
|
|
27
|
+
disabled,
|
|
28
|
+
invalid: errors.length > 0,
|
|
29
|
+
describedById
|
|
30
|
+
})
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
//#endregion
|
|
34
|
+
export { textareaRenderer };
|
|
35
|
+
|
|
36
|
+
//# 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 { useId } from 'react'\nimport { defineFieldRenderer } from '../contract'\nimport { FieldShell } from '../primitives/FieldShell'\nimport { Textarea } from '../primitives/Textarea'\n\nexport const textareaRenderer = 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<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":";;;;;;;AAOA,MAAa,mBAAmB,qBAC9B,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,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,15 @@
|
|
|
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
|
+
warnings: FieldErrors;
|
|
7
|
+
touched: Record<string, boolean>;
|
|
8
|
+
submitting: boolean;
|
|
9
|
+
submitted: boolean;
|
|
10
|
+
submitAttempted: boolean;
|
|
11
|
+
submitError?: string;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { FormState };
|
|
15
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//#region src/react/state.ts
|
|
2
|
+
const initialFormState = (values) => ({
|
|
3
|
+
values,
|
|
4
|
+
errors: {},
|
|
5
|
+
warnings: {},
|
|
6
|
+
touched: {},
|
|
7
|
+
submitting: false,
|
|
8
|
+
submitted: false,
|
|
9
|
+
submitAttempted: false
|
|
10
|
+
});
|
|
11
|
+
/** Changing a value clears that field's prior errors (re-validated by the caller). */
|
|
12
|
+
const formReducer = (state, action) => {
|
|
13
|
+
switch (action.type) {
|
|
14
|
+
case "SET_VALUE": {
|
|
15
|
+
const { [action.name]: _removed, ...restErrors } = state.errors;
|
|
16
|
+
return {
|
|
17
|
+
...state,
|
|
18
|
+
values: {
|
|
19
|
+
...state.values,
|
|
20
|
+
[action.name]: action.value
|
|
21
|
+
},
|
|
22
|
+
errors: restErrors
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
case "TOUCH": return state.touched[action.name] ? state : {
|
|
26
|
+
...state,
|
|
27
|
+
touched: {
|
|
28
|
+
...state.touched,
|
|
29
|
+
[action.name]: true
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
case "SET_FIELD_ISSUES": return {
|
|
33
|
+
...state,
|
|
34
|
+
errors: {
|
|
35
|
+
...state.errors,
|
|
36
|
+
[action.name]: action.errors
|
|
37
|
+
},
|
|
38
|
+
warnings: {
|
|
39
|
+
...state.warnings,
|
|
40
|
+
[action.name]: action.warnings
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
case "SET_ALL_ISSUES": return {
|
|
44
|
+
...state,
|
|
45
|
+
errors: action.errors,
|
|
46
|
+
warnings: action.warnings,
|
|
47
|
+
submitAttempted: true
|
|
48
|
+
};
|
|
49
|
+
case "SUBMIT_START": return {
|
|
50
|
+
...state,
|
|
51
|
+
submitting: true,
|
|
52
|
+
submitError: void 0
|
|
53
|
+
};
|
|
54
|
+
case "SUBMIT_SUCCESS": return {
|
|
55
|
+
...state,
|
|
56
|
+
submitting: false,
|
|
57
|
+
submitted: true
|
|
58
|
+
};
|
|
59
|
+
case "SUBMIT_ERROR": return {
|
|
60
|
+
...state,
|
|
61
|
+
submitting: false,
|
|
62
|
+
submitError: action.message
|
|
63
|
+
};
|
|
64
|
+
default: return state;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
//#endregion
|
|
68
|
+
export { formReducer, initialFormState };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","names":[],"sources":["../../src/react/state.ts"],"sourcesContent":["export type FieldErrors = Record<string, string[]>\n\nexport type FormState = {\n\tvalues: Record<string, unknown>\n\terrors: FieldErrors\n\twarnings: FieldErrors\n\ttouched: Record<string, boolean>\n\tsubmitting: boolean\n\tsubmitted: boolean\n\tsubmitAttempted: boolean\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[]; warnings: string[] }\n\t| { type: 'SET_ALL_ISSUES'; errors: FieldErrors; warnings: FieldErrors }\n\t| { type: 'SUBMIT_START' }\n\t| { type: 'SUBMIT_SUCCESS' }\n\t| { type: 'SUBMIT_ERROR'; message: string }\n\nexport const initialFormState = (values: Record<string, unknown>): FormState => ({\n\tvalues,\n\terrors: {},\n\twarnings: {},\n\ttouched: {},\n\tsubmitting: false,\n\tsubmitted: false,\n\tsubmitAttempted: false,\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\twarnings: { ...state.warnings, [action.name]: action.warnings },\n\t\t\t}\n\t\tcase 'SET_ALL_ISSUES':\n\t\t\treturn { ...state, errors: action.errors, warnings: action.warnings, submitAttempted: true }\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\tdefault:\n\t\t\treturn state\n\t}\n}\n"],"mappings":";AAsBA,MAAa,oBAAoB,YAAgD;CAChF;CACA,QAAQ,CAAC;CACT,UAAU,CAAC;CACX,SAAS,CAAC;CACV,YAAY;CACZ,WAAW;CACX,iBAAiB;AAClB;;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;GACxD,UAAU;IAAE,GAAG,MAAM;KAAW,OAAO,OAAO,OAAO;GAAS;EAC/D;EACD,KAAK,kBACJ,OAAO;GAAE,GAAG;GAAO,QAAQ,OAAO;GAAQ,UAAU,OAAO;GAAU,iBAAiB;EAAK;EAC5F,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,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,24 @@
|
|
|
1
|
+
import { FormDocument } from "./Form.js";
|
|
2
|
+
|
|
3
|
+
//#region src/react/toFormDocument.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Narrows a Payload-generated form document (from `getPayload().findByID()` or `fetch`) to
|
|
6
|
+
* `FormDocument` without an unsafe `as` cast. Handles the small structural mismatches between
|
|
7
|
+
* the auto-generated collection types and what `<Form>` expects:
|
|
8
|
+
* - `fields` may be a typed blocks-union array or null; normalized to `FormFieldInstance[]`
|
|
9
|
+
* - `flow` is stored as opaque JSON; typed as `FormFlow | undefined`
|
|
10
|
+
* - `defaultPresentation` may be null; coerced to `undefined`
|
|
11
|
+
*/
|
|
12
|
+
declare function toFormDocument(form: {
|
|
13
|
+
id: number | string;
|
|
14
|
+
fields?: {
|
|
15
|
+
blockType: string;
|
|
16
|
+
name: string;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}[] | null;
|
|
19
|
+
flow?: unknown;
|
|
20
|
+
defaultPresentation?: string | null;
|
|
21
|
+
}): FormDocument;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { toFormDocument };
|
|
24
|
+
//# sourceMappingURL=toFormDocument.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region src/react/toFormDocument.ts
|
|
3
|
+
/**
|
|
4
|
+
* Narrows a Payload-generated form document (from `getPayload().findByID()` or `fetch`) to
|
|
5
|
+
* `FormDocument` without an unsafe `as` cast. Handles the small structural mismatches between
|
|
6
|
+
* the auto-generated collection types and what `<Form>` expects:
|
|
7
|
+
* - `fields` may be a typed blocks-union array or null; normalized to `FormFieldInstance[]`
|
|
8
|
+
* - `flow` is stored as opaque JSON; typed as `FormFlow | undefined`
|
|
9
|
+
* - `defaultPresentation` may be null; coerced to `undefined`
|
|
10
|
+
*/
|
|
11
|
+
function toFormDocument(form) {
|
|
12
|
+
return {
|
|
13
|
+
id: form.id,
|
|
14
|
+
fields: form.fields ?? [],
|
|
15
|
+
flow: form.flow,
|
|
16
|
+
defaultPresentation: form.defaultPresentation ?? void 0
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { toFormDocument };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=toFormDocument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toFormDocument.js","names":[],"sources":["../../src/react/toFormDocument.ts"],"sourcesContent":["'use client'\n\nimport type { FormFlow } from '../flow/types'\nimport type { FormFieldInstance } from '../submissions/types'\nimport type { FormDocument } from './Form'\n\n/**\n * Narrows a Payload-generated form document (from `getPayload().findByID()` or `fetch`) to\n * `FormDocument` without an unsafe `as` cast. Handles the small structural mismatches between\n * the auto-generated collection types and what `<Form>` expects:\n * - `fields` may be a typed blocks-union array or null; normalized to `FormFieldInstance[]`\n * - `flow` is stored as opaque JSON; typed as `FormFlow | undefined`\n * - `defaultPresentation` may be null; coerced to `undefined`\n */\nexport function toFormDocument(form: {\n\tid: number | string\n\tfields?: { blockType: string; name: string; [key: string]: unknown }[] | null\n\tflow?: unknown\n\tdefaultPresentation?: string | null\n}): FormDocument {\n\treturn {\n\t\tid: form.id,\n\t\tfields: (form.fields ?? []) as FormFieldInstance[],\n\t\tflow: form.flow as FormFlow | undefined,\n\t\tdefaultPresentation: form.defaultPresentation ?? undefined,\n\t}\n}\n"],"mappings":";;;;;;;;;;AAcA,SAAgB,eAAe,MAKd;CAChB,OAAO;EACN,IAAI,KAAK;EACT,QAAS,KAAK,UAAU,CAAC;EACzB,MAAM,KAAK;EACX,qBAAqB,KAAK,uBAAuB,KAAA;CAClD;AACD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/react/uploadFile.d.ts
|
|
2
|
+
type UploadFileInput = {
|
|
3
|
+
file: File; /** Upload collection slug. Defaults to `form-uploads`. */
|
|
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
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/react/uploadFile.ts
|
|
2
|
+
/**
|
|
3
|
+
* Upload one file to a Payload upload collection (`POST {apiRoute}/{collection}`, multipart) and return its
|
|
4
|
+
* id, which the file field stores as its value. The server re-derives the file metadata from the stored doc
|
|
5
|
+
* at submit, so the client is never trusted for it. Pure: inject `fetchImpl` in tests.
|
|
6
|
+
*/
|
|
7
|
+
const uploadFile = async (input) => {
|
|
8
|
+
const { file, collection = "form-uploads", apiRoute = "/api", fetchImpl = fetch } = input;
|
|
9
|
+
const body = new FormData();
|
|
10
|
+
body.append("file", file);
|
|
11
|
+
let response;
|
|
12
|
+
try {
|
|
13
|
+
response = await fetchImpl(`${apiRoute}/${collection}`, {
|
|
14
|
+
method: "POST",
|
|
15
|
+
body
|
|
16
|
+
});
|
|
17
|
+
} catch (error) {
|
|
18
|
+
return {
|
|
19
|
+
ok: false,
|
|
20
|
+
message: error instanceof Error ? error.message : "Network error"
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (!response.ok) return {
|
|
24
|
+
ok: false,
|
|
25
|
+
message: `Upload failed (${response.status})`
|
|
26
|
+
};
|
|
27
|
+
const id = (await response.json().catch(() => ({}))).doc?.id;
|
|
28
|
+
return id == null ? {
|
|
29
|
+
ok: false,
|
|
30
|
+
message: "No id returned"
|
|
31
|
+
} : {
|
|
32
|
+
ok: true,
|
|
33
|
+
id
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
export { uploadFile };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=uploadFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploadFile.js","names":[],"sources":["../../src/react/uploadFile.ts"],"sourcesContent":["export type UploadFileInput = {\n\tfile: File\n\t/** Upload collection slug. Defaults to `form-uploads`. */\n\tcollection?: string\n\tapiRoute?: string\n\tfetchImpl?: typeof fetch\n}\n\nexport type UploadFileResult = { ok: true; id: string | number } | { ok: false; message?: string }\n\n/**\n * Upload one file to a Payload upload collection (`POST {apiRoute}/{collection}`, multipart) and return its\n * id, which the file field stores as its value. The server re-derives the file metadata from the stored doc\n * at submit, so the client is never trusted for it. Pure: inject `fetchImpl` in tests.\n */\nexport const uploadFile = async (input: UploadFileInput): Promise<UploadFileResult> => {\n\tconst { file, collection = 'form-uploads', apiRoute = '/api', fetchImpl = fetch } = input\n\tconst body = new FormData()\n\tbody.append('file', file)\n\tlet response: Response\n\ttry {\n\t\tresponse = await fetchImpl(`${apiRoute}/${collection}`, { method: 'POST', body })\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\treturn { ok: false, message: `Upload failed (${response.status})` }\n\t}\n\tconst data = (await response.json().catch(() => ({}))) as { doc?: { id?: string | number } }\n\tconst id = data.doc?.id\n\treturn id == null ? { ok: false, message: 'No id returned' } : { ok: true, id }\n}\n"],"mappings":";;;;;;AAeA,MAAa,aAAa,OAAO,UAAsD;CACtF,MAAM,EAAE,MAAM,aAAa,gBAAgB,WAAW,QAAQ,YAAY,UAAU;CACpF,MAAM,OAAO,IAAI,SAAS;CAC1B,KAAK,OAAO,QAAQ,IAAI;CACxB,IAAI;CACJ,IAAI;EACH,WAAW,MAAM,UAAU,GAAG,SAAS,GAAG,cAAc;GAAE,QAAQ;GAAQ;EAAK,CAAC;CACjF,SAAS,OAAO;EACf,OAAO;GAAE,IAAI;GAAO,SAAS,iBAAiB,QAAQ,MAAM,UAAU;EAAgB;CACvF;CACA,IAAI,CAAC,SAAS,IACb,OAAO;EAAE,IAAI;EAAO,SAAS,kBAAkB,SAAS,OAAO;CAAG;CAGnE,MAAM,MAAK,MADS,SAAS,KAAK,EAAE,aAAa,CAAC,EAAE,GACpC,KAAK;CACrB,OAAO,MAAM,OAAO;EAAE,IAAI;EAAO,SAAS;CAAiB,IAAI;EAAE,IAAI;EAAM;CAAG;AAC/E"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/react/useField.d.ts
|
|
2
|
+
type UseFieldResult<TValue = unknown> = {
|
|
3
|
+
value: TValue | undefined;
|
|
4
|
+
errors: string[];
|
|
5
|
+
warnings: string[];
|
|
6
|
+
touched: boolean;
|
|
7
|
+
setValue: (value: TValue) => void; /** Mark touched and validate now (call on blur). */
|
|
8
|
+
onBlur: () => void;
|
|
9
|
+
};
|
|
10
|
+
/** Bind one field by name to the form controller: its value, issues, and change/blur handlers. */
|
|
11
|
+
declare const useField: <TValue = unknown>(name: string) => UseFieldResult<TValue>;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { UseFieldResult, useField };
|
|
14
|
+
//# sourceMappingURL=useField.d.ts.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useFormContext } from "./FormContext.js";
|
|
3
|
+
import { useCallback } from "react";
|
|
4
|
+
//#region src/react/useField.ts
|
|
5
|
+
/** Bind one field by name to the form controller: its value, issues, and change/blur handlers. */
|
|
6
|
+
const useField = (name) => {
|
|
7
|
+
const { state, dispatch, validateField } = useFormContext();
|
|
8
|
+
const touched = state.touched[name] ?? false;
|
|
9
|
+
const showIssues = touched || state.submitAttempted;
|
|
10
|
+
const value = state.values[name];
|
|
11
|
+
const setValue = useCallback((next) => {
|
|
12
|
+
dispatch({
|
|
13
|
+
type: "SET_VALUE",
|
|
14
|
+
name,
|
|
15
|
+
value: next
|
|
16
|
+
});
|
|
17
|
+
if (touched || state.submitAttempted) validateField(name, next);
|
|
18
|
+
}, [
|
|
19
|
+
dispatch,
|
|
20
|
+
name,
|
|
21
|
+
touched,
|
|
22
|
+
state.submitAttempted,
|
|
23
|
+
validateField
|
|
24
|
+
]);
|
|
25
|
+
const onBlur = useCallback(() => {
|
|
26
|
+
dispatch({
|
|
27
|
+
type: "TOUCH",
|
|
28
|
+
name
|
|
29
|
+
});
|
|
30
|
+
validateField(name, value);
|
|
31
|
+
}, [
|
|
32
|
+
dispatch,
|
|
33
|
+
name,
|
|
34
|
+
validateField,
|
|
35
|
+
value
|
|
36
|
+
]);
|
|
37
|
+
return {
|
|
38
|
+
value,
|
|
39
|
+
errors: showIssues ? state.errors[name] ?? [] : [],
|
|
40
|
+
warnings: showIssues ? state.warnings[name] ?? [] : [],
|
|
41
|
+
touched,
|
|
42
|
+
setValue,
|
|
43
|
+
onBlur
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
export { useField };
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=useField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useField.js","names":[],"sources":["../../src/react/useField.ts"],"sourcesContent":["'use client'\n\nimport { useCallback } from 'react'\nimport { useFormContext } from './FormContext'\n\nexport type UseFieldResult<TValue = unknown> = {\n\tvalue: TValue | undefined\n\terrors: string[]\n\twarnings: string[]\n\ttouched: boolean\n\tsetValue: (value: TValue) => void\n\t/** Mark touched and validate now (call on blur). */\n\tonBlur: () => void\n}\n\n/** Bind one field by name to the form controller: its value, issues, and change/blur handlers. */\nexport const useField = <TValue = unknown>(name: string): UseFieldResult<TValue> => {\n\tconst { state, dispatch, validateField } = useFormContext()\n\tconst touched = state.touched[name] ?? false\n\tconst showIssues = touched || state.submitAttempted\n\tconst value = state.values[name] as TValue | undefined\n\n\tconst setValue = useCallback(\n\t\t(next: TValue) => {\n\t\t\tdispatch({ type: 'SET_VALUE', name, value: next })\n\t\t\tif (touched || state.submitAttempted) {\n\t\t\t\tvalidateField(name, next)\n\t\t\t}\n\t\t},\n\t\t[dispatch, name, touched, state.submitAttempted, validateField]\n\t)\n\n\tconst onBlur = useCallback(() => {\n\t\tdispatch({ type: 'TOUCH', name })\n\t\tvalidateField(name, value)\n\t}, [dispatch, name, validateField, value])\n\n\treturn {\n\t\tvalue,\n\t\terrors: showIssues ? (state.errors[name] ?? []) : [],\n\t\twarnings: showIssues ? (state.warnings[name] ?? []) : [],\n\t\ttouched,\n\t\tsetValue,\n\t\tonBlur,\n\t}\n}\n"],"mappings":";;;;;AAgBA,MAAa,YAA8B,SAAyC;CACnF,MAAM,EAAE,OAAO,UAAU,kBAAkB,eAAe;CAC1D,MAAM,UAAU,MAAM,QAAQ,SAAS;CACvC,MAAM,aAAa,WAAW,MAAM;CACpC,MAAM,QAAQ,MAAM,OAAO;CAE3B,MAAM,WAAW,aACf,SAAiB;EACjB,SAAS;GAAE,MAAM;GAAa;GAAM,OAAO;EAAK,CAAC;EACjD,IAAI,WAAW,MAAM,iBACpB,cAAc,MAAM,IAAI;CAE1B,GACA;EAAC;EAAU;EAAM;EAAS,MAAM;EAAiB;CAAa,CAC/D;CAEA,MAAM,SAAS,kBAAkB;EAChC,SAAS;GAAE,MAAM;GAAS;EAAK,CAAC;EAChC,cAAc,MAAM,KAAK;CAC1B,GAAG;EAAC;EAAU;EAAM;EAAe;CAAK,CAAC;CAEzC,OAAO;EACN;EACA,QAAQ,aAAc,MAAM,OAAO,SAAS,CAAC,IAAK,CAAC;EACnD,UAAU,aAAc,MAAM,SAAS,SAAS,CAAC,IAAK,CAAC;EACvD;EACA;EACA;CACD;AACD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FormState } from "./state.js";
|
|
2
|
+
|
|
3
|
+
//#region src/react/useFormState.d.ts
|
|
4
|
+
/** The whole form state (values, errors, warnings, touched, submitting, submitted, submitError). */
|
|
5
|
+
declare const useFormState: () => FormState;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { useFormState };
|
|
8
|
+
//# sourceMappingURL=useFormState.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useFormContext } from "./FormContext.js";
|
|
3
|
+
//#region src/react/useFormState.ts
|
|
4
|
+
/** The whole form state (values, errors, warnings, touched, submitting, submitted, submitError). */
|
|
5
|
+
const useFormState = () => useFormContext().state;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { useFormState };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=useFormState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFormState.js","names":[],"sources":["../../src/react/useFormState.ts"],"sourcesContent":["'use client'\n\nimport { useFormContext } from './FormContext'\nimport type { FormState } from './state'\n\n/** The whole form state (values, errors, warnings, touched, submitting, submitted, submitError). */\nexport const useFormState = (): FormState => useFormContext().state\n"],"mappings":";;;;AAMA,MAAa,qBAAgC,eAAe,EAAE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FormStepInfo } from "./FormContext.js";
|
|
2
|
+
|
|
3
|
+
//#region src/react/useFormStep.d.ts
|
|
4
|
+
/** Multi-step navigation state for the current form (single-step default when the form has no flow). */
|
|
5
|
+
declare const useFormStep: () => FormStepInfo;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { useFormStep };
|
|
8
|
+
//# sourceMappingURL=useFormStep.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useFormContext } from "./FormContext.js";
|
|
3
|
+
//#region src/react/useFormStep.ts
|
|
4
|
+
/** Multi-step navigation state for the current form (single-step default when the form has no flow). */
|
|
5
|
+
const useFormStep = () => useFormContext().step;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { useFormStep };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=useFormStep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFormStep.js","names":[],"sources":["../../src/react/useFormStep.ts"],"sourcesContent":["'use client'\n\nimport type { FormStepInfo } from './FormContext'\nimport { useFormContext } from './FormContext'\n\n/** Multi-step navigation state for the current form (single-step default when the form has no flow). */\nexport const useFormStep = (): FormStepInfo => useFormContext().step\n"],"mappings":";;;;AAMA,MAAa,oBAAkC,eAAe,EAAE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { runValidation } from "../validation/runValidation.js";
|
|
2
|
+
//#region src/react/validateField.ts
|
|
3
|
+
/**
|
|
4
|
+
* Run client-side validation for one field, reusing the shared engine in `mode: 'client'` (server-only
|
|
5
|
+
* rules are skipped, no `req`/`payload`). Splits issues into blocking errors and advisory warnings.
|
|
6
|
+
*/
|
|
7
|
+
const validateFieldValue = async (input) => {
|
|
8
|
+
const { field, value, registry, ruleRegistry, answers, locale, t } = input;
|
|
9
|
+
const { errors: issues } = await runValidation({
|
|
10
|
+
field,
|
|
11
|
+
fieldDefinition: registry.get(field.blockType),
|
|
12
|
+
value,
|
|
13
|
+
fieldType: field.blockType,
|
|
14
|
+
ruleRegistry,
|
|
15
|
+
answers,
|
|
16
|
+
locale,
|
|
17
|
+
t,
|
|
18
|
+
operation: "create",
|
|
19
|
+
event: "onChange",
|
|
20
|
+
mode: "client"
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
errors: issues.filter((issue) => issue.severity === "error").map((issue) => issue.message),
|
|
24
|
+
warnings: issues.filter((issue) => issue.severity === "warning").map((issue) => issue.message)
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { validateFieldValue };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=validateField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateField.js","names":[],"sources":["../../src/react/validateField.ts"],"sourcesContent":["import type { FieldTypeRegistry } from '../fields/registry'\nimport type { Translate } from '../fields/types'\nimport type { FormFieldInstance } from '../submissions/types'\nimport type { ValidationRuleRegistry } from '../validation/registry'\nimport { runValidation } from '../validation/runValidation'\n\nexport type ValidateFieldInput = {\n\tfield: FormFieldInstance\n\tvalue: unknown\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\tanswers: Record<string, unknown>\n\tlocale: string\n\tt: Translate\n}\n\nexport type ValidateFieldResult = { errors: string[]; warnings: string[] }\n\n/**\n * Run client-side validation for one field, reusing the shared engine in `mode: 'client'` (server-only\n * rules are skipped, no `req`/`payload`). Splits issues into blocking errors and advisory warnings.\n */\nexport const validateFieldValue = async (\n\tinput: ValidateFieldInput\n): Promise<ValidateFieldResult> => {\n\tconst { field, value, registry, ruleRegistry, answers, locale, t } = input\n\tconst { errors: issues } = await runValidation({\n\t\tfield,\n\t\tfieldDefinition: registry.get(field.blockType),\n\t\tvalue,\n\t\tfieldType: field.blockType,\n\t\truleRegistry,\n\t\tanswers,\n\t\tlocale,\n\t\tt,\n\t\toperation: 'create',\n\t\tevent: 'onChange',\n\t\tmode: 'client',\n\t})\n\treturn {\n\t\terrors: issues.filter((issue) => issue.severity === 'error').map((issue) => issue.message),\n\t\twarnings: issues.filter((issue) => issue.severity === 'warning').map((issue) => issue.message),\n\t}\n}\n"],"mappings":";;;;;;AAsBA,MAAa,qBAAqB,OACjC,UACkC;CAClC,MAAM,EAAE,OAAO,OAAO,UAAU,cAAc,SAAS,QAAQ,MAAM;CACrE,MAAM,EAAE,QAAQ,WAAW,MAAM,cAAc;EAC9C;EACA,iBAAiB,SAAS,IAAI,MAAM,SAAS;EAC7C;EACA,WAAW,MAAM;EACjB;EACA;EACA;EACA;EACA,WAAW;EACX,OAAO;EACP,MAAM;CACP,CAAC;CACD,OAAO;EACN,QAAQ,OAAO,QAAQ,UAAU,MAAM,aAAa,OAAO,EAAE,KAAK,UAAU,MAAM,OAAO;EACzF,UAAU,OAAO,QAAQ,UAAU,MAAM,aAAa,SAAS,EAAE,KAAK,UAAU,MAAM,OAAO;CAC9F;AACD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/recall/interpolate.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Replace `{{ name }}` and `{{ name|fallback }}` tokens. `resolve` returns the recalled value (''
|
|
4
|
+
* when absent); the fallback (or '') is substituted when `resolve` yields ''. Token-free input is
|
|
5
|
+
* returned unchanged, so this is a no-op for ordinary text.
|
|
6
|
+
*/
|
|
7
|
+
declare const interpolate: (template: string, resolve: (name: string) => string) => string;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { interpolate };
|
|
10
|
+
//# sourceMappingURL=interpolate.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//#region src/recall/interpolate.ts
|
|
2
|
+
const TOKEN = /\{\{\s*([^{}|]+?)\s*(?:\|([^{}]*?))?\}\}/g;
|
|
3
|
+
/**
|
|
4
|
+
* Replace `{{ name }}` and `{{ name|fallback }}` tokens. `resolve` returns the recalled value (''
|
|
5
|
+
* when absent); the fallback (or '') is substituted when `resolve` yields ''. Token-free input is
|
|
6
|
+
* returned unchanged, so this is a no-op for ordinary text.
|
|
7
|
+
*/
|
|
8
|
+
const interpolate = (template, resolve) => template.replace(TOKEN, (_match, rawName, rawFallback) => {
|
|
9
|
+
const value = resolve(rawName.trim());
|
|
10
|
+
if (value !== "") return value;
|
|
11
|
+
return rawFallback === void 0 ? "" : rawFallback.trim();
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
14
|
+
export { interpolate };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=interpolate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpolate.js","names":[],"sources":["../../src/recall/interpolate.ts"],"sourcesContent":["const TOKEN = /\\{\\{\\s*([^{}|]+?)\\s*(?:\\|([^{}]*?))?\\}\\}/g\n\n/**\n * Replace `{{ name }}` and `{{ name|fallback }}` tokens. `resolve` returns the recalled value (''\n * when absent); the fallback (or '') is substituted when `resolve` yields ''. Token-free input is\n * returned unchanged, so this is a no-op for ordinary text.\n */\nexport const interpolate = (template: string, resolve: (name: string) => string): string =>\n\ttemplate.replace(TOKEN, (_match, rawName: string, rawFallback?: string) => {\n\t\tconst value = resolve(rawName.trim())\n\t\tif (value !== '') {\n\t\t\treturn value\n\t\t}\n\t\treturn rawFallback === undefined ? '' : rawFallback.trim()\n\t})\n"],"mappings":";AAAA,MAAM,QAAQ;;;;;;AAOd,MAAa,eAAe,UAAkB,YAC7C,SAAS,QAAQ,QAAQ,QAAQ,SAAiB,gBAAyB;CAC1E,MAAM,QAAQ,QAAQ,QAAQ,KAAK,CAAC;CACpC,IAAI,UAAU,IACb,OAAO;CAER,OAAO,gBAAgB,KAAA,IAAY,KAAK,YAAY,KAAK;AAC1D,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { AnyFormFieldDefinition } from "../fields/types.js";
|
|
2
|
+
import { FormFieldInstance } from "../submissions/types.js";
|
|
3
|
+
|
|
4
|
+
//#region src/recall/resolver.d.ts
|
|
5
|
+
type RecallResolver = (name: string) => string;
|
|
6
|
+
/** Derive a value->label map from a select-like field instance's `options`. */
|
|
7
|
+
declare const optionLabelsFor: (field: FormFieldInstance) => Record<string, string> | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Build a recall resolver: `{{name}}` -> the field's current value, formatted via its type's `format`
|
|
10
|
+
* (so a select shows its option label, a checkbox Yes/No, a date localized). Missing field or empty
|
|
11
|
+
* value -> ''. Pure and isomorphic; the renderer and server templates share it.
|
|
12
|
+
*/
|
|
13
|
+
declare const buildRecallResolver: (args: {
|
|
14
|
+
fields: FormFieldInstance[];
|
|
15
|
+
values: Record<string, unknown>;
|
|
16
|
+
registry: Map<string, AnyFormFieldDefinition>;
|
|
17
|
+
locale: string;
|
|
18
|
+
t: (key: string) => string;
|
|
19
|
+
}) => RecallResolver;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { RecallResolver, buildRecallResolver, optionLabelsFor };
|
|
22
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/recall/resolver.ts
|
|
2
|
+
/** Derive a value->label map from a select-like field instance's `options`. */
|
|
3
|
+
const optionLabelsFor = (field) => {
|
|
4
|
+
const options = field.options;
|
|
5
|
+
if (!Array.isArray(options)) return;
|
|
6
|
+
const map = {};
|
|
7
|
+
for (const option of options) if (option && typeof option.value === "string") map[option.value] = option.label ?? option.value;
|
|
8
|
+
return Object.keys(map).length > 0 ? map : void 0;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Build a recall resolver: `{{name}}` -> the field's current value, formatted via its type's `format`
|
|
12
|
+
* (so a select shows its option label, a checkbox Yes/No, a date localized). Missing field or empty
|
|
13
|
+
* value -> ''. Pure and isomorphic; the renderer and server templates share it.
|
|
14
|
+
*/
|
|
15
|
+
const buildRecallResolver = (args) => {
|
|
16
|
+
const byName = new Map(args.fields.map((field) => [field.name, field]));
|
|
17
|
+
return (name) => {
|
|
18
|
+
const field = byName.get(name);
|
|
19
|
+
if (!field) return "";
|
|
20
|
+
const value = args.values[name];
|
|
21
|
+
if (value == null || value === "" || Array.isArray(value) && value.length === 0) return "";
|
|
22
|
+
const definition = args.registry.get(field.blockType);
|
|
23
|
+
if (definition?.format) return definition.format({
|
|
24
|
+
value,
|
|
25
|
+
config: {},
|
|
26
|
+
optionLabels: optionLabelsFor(field),
|
|
27
|
+
locale: args.locale,
|
|
28
|
+
t: args.t
|
|
29
|
+
});
|
|
30
|
+
return Array.isArray(value) ? value.join(", ") : String(value);
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { buildRecallResolver, optionLabelsFor };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=resolver.js.map
|