@10x-media/form-builder 0.1.0-beta.3 → 0.1.0-beta.4
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 +42 -0
- package/README.md +2 -2
- package/dist/actions/body/serializeBody.d.ts +19 -4
- package/dist/actions/body/serializeBody.js +3 -1
- package/dist/actions/body/serializeBody.js.map +1 -1
- package/dist/actions/builtin/confirmation.js +13 -4
- package/dist/actions/builtin/confirmation.js.map +1 -1
- package/dist/actions/builtin/emailTeam.js +13 -4
- package/dist/actions/builtin/emailTeam.js.map +1 -1
- package/dist/actions/builtin/index.d.ts +13 -1
- package/dist/actions/builtin/index.js +18 -7
- package/dist/actions/builtin/index.js.map +1 -1
- package/dist/actions/builtin/signedWebhook.js +2 -16
- package/dist/actions/builtin/signedWebhook.js.map +1 -1
- package/dist/actions/runActions.js +2 -0
- package/dist/actions/runActions.js.map +1 -1
- package/dist/aggregation/resolveResultsRequest.d.ts +22 -6
- package/dist/aggregation/resolveResultsRequest.js +18 -7
- package/dist/aggregation/resolveResultsRequest.js.map +1 -1
- package/dist/client/FlowBuilder.js +98 -53
- package/dist/client/FlowBuilder.js.map +1 -1
- package/dist/client/admin.css +47 -5
- package/dist/client/flowAuthoring.js +35 -0
- package/dist/client/flowAuthoring.js.map +1 -0
- package/dist/client/synthesizeClientField.js +6 -2
- package/dist/client/synthesizeClientField.js.map +1 -1
- package/dist/collections/formSubmissions.js +47 -9
- package/dist/collections/formSubmissions.js.map +1 -1
- package/dist/collections/forms.js +180 -34
- package/dist/collections/forms.js.map +1 -1
- package/dist/conditions/conditionType.js +9 -2
- package/dist/conditions/conditionType.js.map +1 -1
- package/dist/conditions/normalizeConditions.js +2 -1
- package/dist/conditions/normalizeConditions.js.map +1 -1
- package/dist/consent/builtin/index.d.ts +11 -1
- package/dist/consent/builtin/index.js +15 -5
- package/dist/consent/builtin/index.js.map +1 -1
- package/dist/consent/builtin/static.js +7 -3
- package/dist/consent/builtin/static.js.map +1 -1
- package/dist/exports/react.d.ts +10 -6
- package/dist/exports/react.js +6 -2
- package/dist/exports/rsc.d.ts +6 -1
- package/dist/exports/rsc.js +6 -1
- package/dist/exports/types.d.ts +4 -4
- package/dist/fields/buildFieldBlocks.js +17 -8
- package/dist/fields/buildFieldBlocks.js.map +1 -1
- package/dist/fields/builtin/consent.js +8 -4
- package/dist/fields/builtin/consent.js.map +1 -1
- package/dist/fields/builtin/file.js +8 -4
- package/dist/fields/builtin/file.js.map +1 -1
- package/dist/fields/builtin/index.d.ts +11 -1
- package/dist/fields/builtin/index.js +21 -9
- package/dist/fields/builtin/index.js.map +1 -1
- package/dist/fields/builtin/message.js +26 -0
- package/dist/fields/builtin/message.js.map +1 -0
- package/dist/fields/builtin/repeater.js +7 -3
- package/dist/fields/builtin/repeater.js.map +1 -1
- package/dist/fields/builtin/select.js +7 -3
- package/dist/fields/builtin/select.js.map +1 -1
- 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/sharedConfig.js +64 -51
- package/dist/fields/sharedConfig.js.map +1 -1
- package/dist/fields/types.d.ts +7 -2
- package/dist/flow/normalizeFlow.js +7 -1
- package/dist/flow/normalizeFlow.js.map +1 -1
- package/dist/flow/stepLabel.js +15 -0
- package/dist/flow/stepLabel.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 +60 -0
- package/dist/form/toFormDocument.js +39 -0
- package/dist/form/toFormDocument.js.map +1 -0
- package/dist/form/types.d.ts +48 -0
- package/dist/index.d.ts +69 -18
- package/dist/index.js +24 -13
- package/dist/index.js.map +1 -1
- package/dist/plugin/registerCollections.js +15 -36
- package/dist/plugin/registerCollections.js.map +1 -1
- package/dist/plugin/uploadsCollection.d.ts +11 -0
- package/dist/plugin/uploadsCollection.js +44 -0
- package/dist/plugin/uploadsCollection.js.map +1 -0
- package/dist/poll/applyPollOptions.js +17 -0
- package/dist/poll/applyPollOptions.js.map +1 -0
- package/dist/poll/buildPollOptionSourceFields.js +53 -0
- package/dist/poll/buildPollOptionSourceFields.js.map +1 -0
- package/dist/poll/definePollOptionSource.d.ts +35 -0
- package/dist/poll/definePollOptionSource.js +6 -0
- package/dist/poll/definePollOptionSource.js.map +1 -0
- package/dist/poll/registry.d.ts +16 -0
- package/dist/poll/registry.js +16 -0
- package/dist/poll/registry.js.map +1 -0
- package/dist/poll/resolvePollOptions.d.ts +28 -0
- package/dist/poll/resolvePollOptions.js +64 -0
- package/dist/poll/resolvePollOptions.js.map +1 -0
- package/dist/poll/resolvePollOutcome.d.ts +21 -0
- package/dist/poll/resolvePollOutcome.js +36 -0
- package/dist/poll/resolvePollOutcome.js.map +1 -0
- package/dist/prefill/valuesFromSearchParams.js +1 -1
- package/dist/prefill/valuesFromSearchParams.js.map +1 -1
- package/dist/presentations/types.d.ts +3 -2
- package/dist/react/Form.d.ts +13 -31
- package/dist/react/Form.js +96 -83
- package/dist/react/Form.js.map +1 -1
- package/dist/react/FormContext.d.ts +35 -1
- package/dist/react/FormContext.js.map +1 -1
- 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/FormResults.d.ts +6 -3
- package/dist/react/FormResults.js +37 -29
- package/dist/react/FormResults.js.map +1 -1
- 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/Poll.d.ts +17 -6
- package/dist/react/Poll.js +66 -18
- package/dist/react/Poll.js.map +1 -1
- package/dist/react/fetchResults.d.ts +1 -1
- package/dist/react/fetchResults.js +1 -1
- package/dist/react/fetchResults.js.map +1 -1
- package/dist/react/renderers/file.js +5 -1
- package/dist/react/renderers/file.js.map +1 -1
- package/dist/react/renderers/index.js +2 -0
- package/dist/react/renderers/index.js.map +1 -1
- package/dist/react/renderers/message.js +35 -0
- package/dist/react/renderers/message.js.map +1 -0
- package/dist/react/state.d.ts +25 -1
- package/dist/react/state.js +14 -1
- package/dist/react/state.js.map +1 -1
- package/dist/react/uploadFile.d.ts +2 -2
- package/dist/react/uploadFile.js +1 -1
- package/dist/react/uploadFile.js.map +1 -1
- package/dist/submissions/runSubmission.js +70 -33
- package/dist/submissions/runSubmission.js.map +1 -1
- package/dist/submissions/validateSubmission.js +41 -7
- package/dist/submissions/validateSubmission.js.map +1 -1
- 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/de.js +219 -0
- package/dist/translations/de.js.map +1 -0
- package/dist/translations/en.js +45 -6
- package/dist/translations/en.js.map +1 -1
- package/dist/translations/index.d.ts +2 -1
- package/dist/translations/index.js +6 -2
- package/dist/translations/index.js.map +1 -1
- package/dist/translations/keys.d.ts +43 -4
- package/dist/translations/keys.js +44 -5
- package/dist/translations/keys.js.map +1 -1
- package/dist/uploads/types.d.ts +1 -2
- package/dist/validation/validateUrl.js +22 -0
- package/dist/validation/validateUrl.js.map +1 -0
- package/package.json +2 -1
- package/styles/form-builder.css +10 -0
- package/dist/collections/uploads.d.ts +0 -30
- package/dist/collections/uploads.js +0 -55
- package/dist/collections/uploads.js.map +0 -1
- package/dist/presentations/registry.d.ts +0 -15
- package/dist/presentations/registry.js +0 -15
- package/dist/presentations/registry.js.map +0 -1
- package/dist/react/toFormDocument.d.ts +0 -24
- package/dist/react/toFormDocument.js +0 -22
- package/dist/react/toFormDocument.js.map +0 -1
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
import { localizedIf } from "../../fields/localizedIf.js";
|
|
1
2
|
import { keys } from "../../translations/keys.js";
|
|
2
3
|
import { labelFor } from "../../translations/server.js";
|
|
3
4
|
import { defineConsentSource } from "../defineConsentSource.js";
|
|
4
5
|
//#region src/consent/builtin/static.ts
|
|
5
|
-
|
|
6
|
+
/** The link `label` is visitor-facing text and follows `localize`; `url` and `version` are identifiers and never do. */
|
|
7
|
+
const buildStaticSource = (localize) => defineConsentSource({
|
|
6
8
|
type: "static",
|
|
7
9
|
label: keys.consentSourceStatic,
|
|
8
10
|
config: [
|
|
9
11
|
{
|
|
10
12
|
name: "label",
|
|
11
13
|
type: "text",
|
|
12
|
-
label: labelFor(keys.consentConfigLabel)
|
|
14
|
+
label: labelFor(keys.consentConfigLabel),
|
|
15
|
+
...localizedIf(localize)
|
|
13
16
|
},
|
|
14
17
|
{
|
|
15
18
|
name: "url",
|
|
@@ -38,7 +41,8 @@ const staticSource = defineConsentSource({
|
|
|
38
41
|
};
|
|
39
42
|
}
|
|
40
43
|
});
|
|
44
|
+
buildStaticSource(true);
|
|
41
45
|
//#endregion
|
|
42
|
-
export {
|
|
46
|
+
export { buildStaticSource };
|
|
43
47
|
|
|
44
48
|
//# sourceMappingURL=static.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static.js","names":[],"sources":["../../../src/consent/builtin/static.ts"],"sourcesContent":["import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineConsentSource } from '../defineConsentSource'\n\ntype StaticConfig = { label?: string; url?: string; version?: string }\n\nexport const
|
|
1
|
+
{"version":3,"file":"static.js","names":[],"sources":["../../../src/consent/builtin/static.ts"],"sourcesContent":["import { localizedIf } from '../../fields/localizedIf'\nimport { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineConsentSource } from '../defineConsentSource'\n\ntype StaticConfig = { label?: string; url?: string; version?: string }\n\n/** The link `label` is visitor-facing text and follows `localize`; `url` and `version` are identifiers and never do. */\nexport const buildStaticSource = (localize: boolean) =>\n\tdefineConsentSource<StaticConfig>({\n\t\ttype: 'static',\n\t\tlabel: keys.consentSourceStatic,\n\t\tconfig: [\n\t\t\t{\n\t\t\t\tname: 'label',\n\t\t\t\ttype: 'text',\n\t\t\t\tlabel: labelFor(keys.consentConfigLabel),\n\t\t\t\t...localizedIf(localize),\n\t\t\t},\n\t\t\t{ name: 'url', type: 'text', label: labelFor(keys.consentConfigUrl) },\n\t\t\t{ name: 'version', type: 'text', label: labelFor(keys.consentConfigVersion) },\n\t\t],\n\t\tresolve({ config }) {\n\t\t\tconst label = String(config.label ?? '')\n\t\t\tconst url = String(config.url ?? '')\n\t\t\tconst version = config.version ? String(config.version) : undefined\n\t\t\treturn {\n\t\t\t\tlinks: [{ label, url }],\n\t\t\t\t...(version ? { versionRef: version, versionLabel: version } : {}),\n\t\t\t}\n\t\t},\n\t})\n\nexport const staticSource = buildStaticSource(true)\n"],"mappings":";;;;;;AAQA,MAAa,qBAAqB,aACjC,oBAAkC;CACjC,MAAM;CACN,OAAO,KAAK;CACZ,QAAQ;EACP;GACC,MAAM;GACN,MAAM;GACN,OAAO,SAAS,KAAK,kBAAkB;GACvC,GAAG,YAAY,QAAQ;EACxB;EACA;GAAE,MAAM;GAAO,MAAM;GAAQ,OAAO,SAAS,KAAK,gBAAgB;EAAE;EACpE;GAAE,MAAM;GAAW,MAAM;GAAQ,OAAO,SAAS,KAAK,oBAAoB;EAAE;CAC7E;CACA,QAAQ,EAAE,UAAU;EACnB,MAAM,QAAQ,OAAO,OAAO,SAAS,EAAE;EACvC,MAAM,MAAM,OAAO,OAAO,OAAO,EAAE;EACnC,MAAM,UAAU,OAAO,UAAU,OAAO,OAAO,OAAO,IAAI,KAAA;EAC1D,OAAO;GACN,OAAO,CAAC;IAAE;IAAO;GAAI,CAAC;GACtB,GAAI,UAAU;IAAE,YAAY;IAAS,cAAc;GAAQ,IAAI,CAAC;EACjE;CACD;AACD,CAAC;AAE0B,kBAAkB,IAAI"}
|
package/dist/exports/react.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { FormFieldInstance } from "../submissions/types.js";
|
|
1
|
+
import { FormFieldInstance, SubmissionValue } from "../submissions/types.js";
|
|
2
|
+
import { BodyContext, serializeBody } from "../actions/body/serializeBody.js";
|
|
2
3
|
import { AggregationBucket, FieldAggregation } from "../aggregation/types.js";
|
|
3
4
|
import { CalcExpression } from "../calc/types.js";
|
|
4
5
|
import { computeCalcFields } from "../calc/computeCalcFields.js";
|
|
5
6
|
import { evaluateCalc } from "../calc/evaluate.js";
|
|
6
7
|
import { evaluateCondition } from "../conditions/evaluate.js";
|
|
7
8
|
import { firstStepId, isTerminalStepId, resolveNextStepId, stepFieldNames } from "../flow/engine.js";
|
|
9
|
+
import { FormDisplaySettings, FormDocument, FormPollSettings, FormResponseSettings } from "../form/types.js";
|
|
10
|
+
import { toFormDocument } from "../form/toFormDocument.js";
|
|
8
11
|
import { PrefillOptions, valuesFromSearchParams } from "../prefill/valuesFromSearchParams.js";
|
|
9
12
|
import { CaptchaWidgetHandle } from "../react/captcha/types.js";
|
|
10
13
|
import { HCAPTCHA_SCRIPT_URL, HcaptchaCaptcha, HcaptchaCaptchaProps } from "../react/captcha/HcaptchaCaptcha.js";
|
|
@@ -12,15 +15,17 @@ import { RECAPTCHA_SCRIPT_URL, RecaptchaCaptcha, RecaptchaCaptchaHandle, Recaptc
|
|
|
12
15
|
import { TURNSTILE_SCRIPT_URL, TurnstileCaptcha, TurnstileCaptchaProps } from "../react/captcha/TurnstileCaptcha.js";
|
|
13
16
|
import { cn } from "../react/cn.js";
|
|
14
17
|
import { FieldRenderer, FieldRendererProps, RendererTranslate, defineFieldRenderer } from "../react/contract.js";
|
|
18
|
+
import { BackButtonRenderProps, FormControls, FormControlsProps, NextButtonRenderProps, SubmitButtonRenderProps } from "../react/FormControls.js";
|
|
15
19
|
import { FormPresentation, PresentationWrapperProps } from "../react/presentation/types.js";
|
|
16
20
|
import { PresentationOption, PresentationRegistry, PresentationsConfig, resolvePresentations } from "../react/presentation/registry.js";
|
|
17
21
|
import { RendererOption, RendererRegistry, RenderersConfig, resolveRenderers } from "../react/registry.js";
|
|
18
22
|
import { SubmitFormResult, SubmitHandler, submitForm } from "../react/submitForm.js";
|
|
19
|
-
import {
|
|
20
|
-
import { FormState } from "../react/state.js";
|
|
21
|
-
import { FormStepInfo } from "../react/FormContext.js";
|
|
23
|
+
import { Form, FormProps } from "../react/Form.js";
|
|
24
|
+
import { FieldErrors, FormAction, FormState } from "../react/state.js";
|
|
25
|
+
import { FormContextValue, FormControlLabels, FormStepInfo, useFormContext } from "../react/FormContext.js";
|
|
22
26
|
import { FieldWidth, FormLayout, FormLayoutProps, widthProps } from "../react/FormLayout.js";
|
|
23
27
|
import { FormResults, FormResultsProps } from "../react/FormResults.js";
|
|
28
|
+
import { FormSteps, FormStepsProps } from "../react/FormSteps.js";
|
|
24
29
|
import { FetchResultsInput, FetchResultsResult, fetchFormResults } from "../react/fetchResults.js";
|
|
25
30
|
import { Honeypot, HoneypotProps } from "../react/Honeypot.js";
|
|
26
31
|
import { Poll, PollProps } from "../react/Poll.js";
|
|
@@ -36,7 +41,6 @@ import { Input, InputProps } from "../react/primitives/Input.js";
|
|
|
36
41
|
import { Select, SelectOption, SelectProps } from "../react/primitives/Select.js";
|
|
37
42
|
import { Textarea, TextareaProps } from "../react/primitives/Textarea.js";
|
|
38
43
|
import { defaultRenderers } from "../react/renderers/index.js";
|
|
39
|
-
import { toFormDocument } from "../react/toFormDocument.js";
|
|
40
44
|
import { UploadFileInput, UploadFileResult, uploadFile } from "../react/uploadFile.js";
|
|
41
45
|
import { UseFieldResult, useField } from "../react/useField.js";
|
|
42
46
|
import { useFormState } from "../react/useFormState.js";
|
|
@@ -47,4 +51,4 @@ import { CAPTCHA_TOKEN_KEY, DEFAULT_HONEYPOT_FIELD } from "../spam/constants.js"
|
|
|
47
51
|
import { en } from "../translations/en.js";
|
|
48
52
|
import { makeTranslate } from "../translations/makeTranslate.js";
|
|
49
53
|
import { formatBytes } from "../uploads/formatBytes.js";
|
|
50
|
-
export { type AggregationBucket, type BackButtonRenderProps, Backdrop, type BackdropProps, CAPTCHA_TOKEN_KEY, type CalcExpression, type CaptchaWidgetHandle, Checkbox, type CheckboxProps, DEFAULT_HONEYPOT_FIELD, DialogSurface, type DialogSurfaceProps, type FetchResultsInput, type FetchResultsResult, type FieldAggregation, type FieldRenderer, type FieldRendererProps, FieldShell, type FieldShellProps, type FieldWidth, Form, type FormDocument, type FormFieldInstance, FormLayout, type FormLayoutProps, type FormPresentation, type FormProps, FormResults, type FormResultsProps, type FormState, type FormStepInfo, HCAPTCHA_SCRIPT_URL, HcaptchaCaptcha, type HcaptchaCaptchaProps, Honeypot, type HoneypotProps, Input, type InputProps, type NextButtonRenderProps, Poll, type PollProps, type PrefillOptions, type PresentationOption, type PresentationRegistry, type PresentationWrapperProps, type PresentationsConfig, RECAPTCHA_SCRIPT_URL, type RecallResolver, RecaptchaCaptcha, type RecaptchaCaptchaHandle, type RecaptchaCaptchaProps, type RendererOption, type RendererRegistry, type RendererTranslate, type RenderersConfig, Select, type SelectOption, type SelectProps, type SubmitButtonRenderProps, type SubmitFormResult, type SubmitHandler, TURNSTILE_SCRIPT_URL, Textarea, type TextareaProps, TurnstileCaptcha, type TurnstileCaptchaProps, type UploadFileInput, type UploadFileResult, type UseDismissOptions, type UseFieldResult, buildRecallResolver, cn, computeCalcFields, defaultPresentations, defaultRenderers, defineFieldRenderer, en, evaluateCalc, evaluateCondition, fetchFormResults, firstStepId, formatBytes, interpolate, isTerminalStepId, makeTranslate, resolveNextStepId, resolvePresentations, resolveRenderers, stepFieldNames, submitForm, toFormDocument, uploadFile, useDismiss, useField, useFocusTrap, useFormState, useFormStep, useScrollLock, valuesFromSearchParams, widthProps };
|
|
54
|
+
export { type AggregationBucket, type BackButtonRenderProps, Backdrop, type BackdropProps, type BodyContext, CAPTCHA_TOKEN_KEY, type CalcExpression, type CaptchaWidgetHandle, Checkbox, type CheckboxProps, DEFAULT_HONEYPOT_FIELD, DialogSurface, type DialogSurfaceProps, type FetchResultsInput, type FetchResultsResult, type FieldAggregation, type FieldErrors, type FieldRenderer, type FieldRendererProps, FieldShell, type FieldShellProps, type FieldWidth, Form, type FormAction, type FormContextValue, type FormControlLabels, FormControls, type FormControlsProps, type FormDisplaySettings, type FormDocument, type FormFieldInstance, FormLayout, type FormLayoutProps, type FormPollSettings, type FormPresentation, type FormProps, type FormResponseSettings, FormResults, type FormResultsProps, type FormState, type FormStepInfo, FormSteps, type FormStepsProps, HCAPTCHA_SCRIPT_URL, HcaptchaCaptcha, type HcaptchaCaptchaProps, Honeypot, type HoneypotProps, Input, type InputProps, type NextButtonRenderProps, Poll, type PollProps, type PrefillOptions, type PresentationOption, type PresentationRegistry, type PresentationWrapperProps, type PresentationsConfig, RECAPTCHA_SCRIPT_URL, type RecallResolver, RecaptchaCaptcha, type RecaptchaCaptchaHandle, type RecaptchaCaptchaProps, type RendererOption, type RendererRegistry, type RendererTranslate, type RenderersConfig, Select, type SelectOption, type SelectProps, type SubmissionValue, type SubmitButtonRenderProps, type SubmitFormResult, type SubmitHandler, TURNSTILE_SCRIPT_URL, Textarea, type TextareaProps, TurnstileCaptcha, type TurnstileCaptchaProps, type UploadFileInput, type UploadFileResult, type UseDismissOptions, type UseFieldResult, buildRecallResolver, cn, computeCalcFields, defaultPresentations, defaultRenderers, defineFieldRenderer, en, evaluateCalc, evaluateCondition, fetchFormResults, firstStepId, formatBytes, interpolate, isTerminalStepId, makeTranslate, resolveNextStepId, resolvePresentations, resolveRenderers, serializeBody, stepFieldNames, submitForm, toFormDocument, uploadFile, useDismiss, useField, useFocusTrap, useFormContext, useFormState, useFormStep, useScrollLock, valuesFromSearchParams, widthProps };
|
package/dist/exports/react.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { interpolate } from "../recall/interpolate.js";
|
|
3
|
+
import { serializeBody } from "../actions/body/serializeBody.js";
|
|
3
4
|
import { CAPTCHA_TOKEN_KEY, DEFAULT_HONEYPOT_FIELD } from "../spam/constants.js";
|
|
4
5
|
import { evaluateCalc } from "../calc/evaluate.js";
|
|
5
6
|
import { computeCalcFields } from "../calc/computeCalcFields.js";
|
|
6
7
|
import { evaluateCondition } from "../conditions/evaluate.js";
|
|
7
8
|
import { en } from "../translations/en.js";
|
|
9
|
+
import { toFormDocument } from "../form/toFormDocument.js";
|
|
8
10
|
import { valuesFromSearchParams } from "../prefill/valuesFromSearchParams.js";
|
|
9
11
|
import { buildRecallResolver } from "../recall/resolver.js";
|
|
10
12
|
import { formatBytes } from "../uploads/formatBytes.js";
|
|
@@ -15,6 +17,8 @@ import { TURNSTILE_SCRIPT_URL, TurnstileCaptcha } from "../react/captcha/Turnsti
|
|
|
15
17
|
import { cn } from "../react/cn.js";
|
|
16
18
|
import { defineFieldRenderer } from "../react/contract.js";
|
|
17
19
|
import { makeTranslate } from "../translations/makeTranslate.js";
|
|
20
|
+
import { useFormContext } from "../react/FormContext.js";
|
|
21
|
+
import { FormControls } from "../react/FormControls.js";
|
|
18
22
|
import { FormLayout, widthProps } from "../react/FormLayout.js";
|
|
19
23
|
import { Honeypot } from "../react/Honeypot.js";
|
|
20
24
|
import { Backdrop } from "../react/presentation/Backdrop.js";
|
|
@@ -36,9 +40,9 @@ import { defaultRenderers } from "../react/renderers/index.js";
|
|
|
36
40
|
import { submitForm } from "../react/submitForm.js";
|
|
37
41
|
import { Form } from "../react/Form.js";
|
|
38
42
|
import { FormResults } from "../react/FormResults.js";
|
|
43
|
+
import { FormSteps } from "../react/FormSteps.js";
|
|
39
44
|
import { fetchFormResults } from "../react/fetchResults.js";
|
|
40
45
|
import { Poll } from "../react/Poll.js";
|
|
41
|
-
import { toFormDocument } from "../react/toFormDocument.js";
|
|
42
46
|
import { useFormState } from "../react/useFormState.js";
|
|
43
47
|
import { useFormStep } from "../react/useFormStep.js";
|
|
44
|
-
export { Backdrop, CAPTCHA_TOKEN_KEY, Checkbox, DEFAULT_HONEYPOT_FIELD, DialogSurface, FieldShell, Form, FormLayout, FormResults, HCAPTCHA_SCRIPT_URL, HcaptchaCaptcha, Honeypot, Input, Poll, RECAPTCHA_SCRIPT_URL, RecaptchaCaptcha, Select, TURNSTILE_SCRIPT_URL, Textarea, TurnstileCaptcha, buildRecallResolver, cn, computeCalcFields, defaultPresentations, defaultRenderers, defineFieldRenderer, en, evaluateCalc, evaluateCondition, fetchFormResults, firstStepId, formatBytes, interpolate, isTerminalStepId, makeTranslate, resolveNextStepId, resolvePresentations, resolveRenderers, stepFieldNames, submitForm, toFormDocument, uploadFile, useDismiss, useField, useFocusTrap, useFormState, useFormStep, useScrollLock, valuesFromSearchParams, widthProps };
|
|
48
|
+
export { Backdrop, CAPTCHA_TOKEN_KEY, Checkbox, DEFAULT_HONEYPOT_FIELD, DialogSurface, FieldShell, Form, FormControls, FormLayout, FormResults, FormSteps, HCAPTCHA_SCRIPT_URL, HcaptchaCaptcha, Honeypot, Input, Poll, RECAPTCHA_SCRIPT_URL, RecaptchaCaptcha, Select, TURNSTILE_SCRIPT_URL, Textarea, TurnstileCaptcha, buildRecallResolver, cn, computeCalcFields, defaultPresentations, defaultRenderers, defineFieldRenderer, en, evaluateCalc, evaluateCondition, fetchFormResults, firstStepId, formatBytes, interpolate, isTerminalStepId, makeTranslate, resolveNextStepId, resolvePresentations, resolveRenderers, serializeBody, stepFieldNames, submitForm, toFormDocument, uploadFile, useDismiss, useField, useFocusTrap, useFormContext, useFormState, useFormStep, useScrollLock, valuesFromSearchParams, widthProps };
|
package/dist/exports/rsc.d.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
import { toFormDocument } from "../form/toFormDocument.js";
|
|
2
|
+
import { isPollClosed } from "../form/pollState.js";
|
|
3
|
+
import { resolvePollOptions } from "../poll/resolvePollOptions.js";
|
|
4
|
+
import { resolvePollOutcome } from "../poll/resolvePollOutcome.js";
|
|
1
5
|
import { SubmissionAnswers } from "../submissions/SubmissionAnswers.js";
|
|
2
|
-
|
|
6
|
+
import { hasVotedCookie, votedCookieName } from "../submissions/votedCookie.js";
|
|
7
|
+
export { SubmissionAnswers, hasVotedCookie, isPollClosed, resolvePollOptions, resolvePollOutcome, toFormDocument, votedCookieName };
|
package/dist/exports/rsc.js
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
import { isPollClosed } from "../form/pollState.js";
|
|
2
|
+
import { resolvePollOptions } from "../poll/resolvePollOptions.js";
|
|
3
|
+
import { hasVotedCookie, votedCookieName } from "../submissions/votedCookie.js";
|
|
4
|
+
import { toFormDocument } from "../form/toFormDocument.js";
|
|
5
|
+
import { resolvePollOutcome } from "../poll/resolvePollOutcome.js";
|
|
1
6
|
import { SubmissionAnswers } from "../submissions/SubmissionAnswers.js";
|
|
2
|
-
export { SubmissionAnswers };
|
|
7
|
+
export { SubmissionAnswers, hasVotedCookie, isPollClosed, resolvePollOptions, resolvePollOutcome, toFormDocument, votedCookieName };
|
package/dist/exports/types.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { FormFieldInstance, SubmissionDescriptor, SubmissionFieldError, Submissi
|
|
|
4
4
|
import { AggregationBucket, AggregationRow, FieldAggregation, FieldMeta, SubmissionStatusFilter } from "../aggregation/types.js";
|
|
5
5
|
import { CalcExpression } from "../calc/types.js";
|
|
6
6
|
import { FlowStep, FlowTransition, FormFlow } from "../flow/types.js";
|
|
7
|
+
import { FormDisplaySettings, FormDocument, FormPollSettings, FormResponseSettings } from "../form/types.js";
|
|
7
8
|
import { FieldTypeOption, FieldTypeRegistry, FieldTypesConfig } from "../fields/registry.js";
|
|
8
9
|
import { PrefillOptions } from "../prefill/valuesFromSearchParams.js";
|
|
9
10
|
import { FormEvent, FormEventSink } from "../events/types.js";
|
|
@@ -15,14 +16,13 @@ import { ActionOption, ActionRegistry, ActionsConfig } from "../actions/registry
|
|
|
15
16
|
import { ActionResult } from "../actions/runActions.js";
|
|
16
17
|
import { AggregateFieldResponsesArgs, AggregateFormResponsesArgs } from "../aggregation/aggregateResponses.js";
|
|
17
18
|
import { ResolveResultsRequestArgs, ResolveResultsRequestResult } from "../aggregation/resolveResultsRequest.js";
|
|
18
|
-
import { CollectionOverrides, FieldsOverride } from "../plugin/collectionOverrides.js";
|
|
19
|
-
import { UploadsCollectionConfig, UploadsOption } from "../collections/uploads.js";
|
|
20
19
|
import { FieldCondition } from "../conditions/types.js";
|
|
21
20
|
import { AnyConsentSource, ConsentLink, ConsentResolveArgs, ConsentResolved, ConsentSource } from "../consent/defineConsentSource.js";
|
|
22
21
|
import { ConsentSourceOption, ConsentSourceRegistry, ConsentSourcesConfig } from "../consent/registry.js";
|
|
23
22
|
import { ConsentProof } from "../consent/captureConsent.js";
|
|
24
|
-
import {
|
|
23
|
+
import { CollectionOverrides, FieldsOverride } from "../plugin/collectionOverrides.js";
|
|
25
24
|
import { CaptchaProvider, CaptchaVerifyArgs, IdentifyFn, RateLimitCheckArgs, RateLimitConfig, RateLimitResult, RateLimiter, SpamConfig, SpamMetadataConfig, SpamOption } from "../spam/types.js";
|
|
25
|
+
import { UploadsOption } from "../plugin/uploadsCollection.js";
|
|
26
26
|
import { ValidationRuleOption, ValidationRuleRegistry, ValidationRulesConfig } from "../validation/registry.js";
|
|
27
27
|
import { FormBuilderPluginOptions } from "../index.js";
|
|
28
|
-
export type { ActionDefinition, ActionOption, ActionRegistry, ActionResult, ActionRunArgs, ActionsConfig, AggregateFieldResponsesArgs, AggregateFormResponsesArgs, AggregationBucket, AggregationRow, AnyActionDefinition, AnyConsentSource, AnyFormFieldDefinition, AnyValidationRuleDefinition, CalcExpression, CaptchaProvider, CaptchaVerifyArgs, CollectionOverrides, ConsentLink, ConsentProof, ConsentResolveArgs, ConsentResolved, ConsentSource, ConsentSourceOption, ConsentSourceRegistry, ConsentSourcesConfig, FieldAggregation, FieldCondition, FieldMeta, FieldTypeOption, FieldTypeRegistry, FieldTypesConfig, FieldsOverride, FileFieldConfig, FileRef, FileRefError, FlowStep, FlowTransition, FormBuilderPluginOptions, FormEvent, FormEventSink, FormFieldDefinition, FormFieldFormat, FormFieldInstance, FormFieldValidate, FormFieldValueKind, FormFlow, IdentifyFn, PrefillOptions, PresentationDensity, PresentationDescriptor,
|
|
28
|
+
export type { ActionDefinition, ActionOption, ActionRegistry, ActionResult, ActionRunArgs, ActionsConfig, AggregateFieldResponsesArgs, AggregateFormResponsesArgs, AggregationBucket, AggregationRow, AnyActionDefinition, AnyConsentSource, AnyFormFieldDefinition, AnyValidationRuleDefinition, CalcExpression, CaptchaProvider, CaptchaVerifyArgs, CollectionOverrides, ConsentLink, ConsentProof, ConsentResolveArgs, ConsentResolved, ConsentSource, ConsentSourceOption, ConsentSourceRegistry, ConsentSourcesConfig, FieldAggregation, FieldCondition, FieldMeta, FieldTypeOption, FieldTypeRegistry, FieldTypesConfig, FieldsOverride, FileFieldConfig, FileRef, FileRefError, FlowStep, FlowTransition, FormBuilderPluginOptions, FormDisplaySettings, FormDocument, FormEvent, FormEventSink, FormFieldDefinition, FormFieldFormat, FormFieldInstance, FormFieldValidate, FormFieldValueKind, FormFlow, FormPollSettings, FormResponseSettings, IdentifyFn, PrefillOptions, PresentationDensity, PresentationDescriptor, PresentationSurface, RateLimitCheckArgs, RateLimitConfig, RateLimitResult, RateLimiter, RecallResolver, ResolveResultsRequestArgs, ResolveResultsRequestResult, SpamConfig, SpamMetadataConfig, SpamOption, SubmissionDescriptor, SubmissionFieldError, SubmissionStatusFilter, SubmissionValue, UploadsOption, ValidationRuleDefinition, ValidationRuleOption, ValidationRuleRegistry, ValidationRuleResult, ValidationRulesConfig, ValidationSeverity };
|
|
@@ -5,12 +5,16 @@ import { buildConsentSourceConfig } from "../consent/buildConsentSourceConfig.js
|
|
|
5
5
|
import { buildRuleBlocks } from "../validation/buildRuleBlocks.js";
|
|
6
6
|
import { fieldBlockTabs } from "./sharedConfig.js";
|
|
7
7
|
//#region src/fields/buildFieldBlocks.ts
|
|
8
|
+
/** Whether `fields` contains a field named `name`, descending into presentational rows. */
|
|
9
|
+
const hasNameField = (fields) => fields.some((f) => {
|
|
10
|
+
if ("name" in f && f.name === "name") return true;
|
|
11
|
+
return f.type === "row" && hasNameField(f.fields);
|
|
12
|
+
});
|
|
8
13
|
/** The tab whose fields hold the shared basics and type config, found by the `name` field it carries. */
|
|
9
14
|
const fieldTabOf = (block) => {
|
|
10
|
-
return block.fields.find((f) => f.type === "tabs")?.tabs.find((tab) => tab.fields
|
|
15
|
+
return block.fields.find((f) => f.type === "tabs")?.tabs.find((tab) => hasNameField(tab.fields))?.fields;
|
|
11
16
|
};
|
|
12
|
-
|
|
13
|
-
const buildFieldBlocks = (registry, ruleRegistry, consentRegistry) => {
|
|
17
|
+
const buildFieldBlocks = ({ registry, ruleRegistry, consentRegistry, localize = true }) => {
|
|
14
18
|
const conditionTypes = buildConditionTypeMap(registry);
|
|
15
19
|
const blocks = [];
|
|
16
20
|
for (const definition of registry.values()) {
|
|
@@ -30,11 +34,16 @@ const buildFieldBlocks = (registry, ruleRegistry, consentRegistry) => {
|
|
|
30
34
|
singular: labelFor(definition.label),
|
|
31
35
|
plural: labelFor(definition.label)
|
|
32
36
|
},
|
|
33
|
-
fields: [fieldBlockTabs(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
fields: [fieldBlockTabs({
|
|
38
|
+
conditionTypes,
|
|
39
|
+
typeConfig,
|
|
40
|
+
validations: {
|
|
41
|
+
name: "validations",
|
|
42
|
+
type: "blocks",
|
|
43
|
+
label: labelFor(keys.validationsLabel),
|
|
44
|
+
blocks: buildRuleBlocks(ruleRegistry, definition.type)
|
|
45
|
+
},
|
|
46
|
+
localize
|
|
38
47
|
})]
|
|
39
48
|
});
|
|
40
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildFieldBlocks.js","names":[],"sources":["../../src/fields/buildFieldBlocks.ts"],"sourcesContent":["import type { Block, Field, TabsField } from 'payload'\nimport { buildConditionTypeMap } from '../conditions/conditionType'\nimport { buildConsentSourceConfig } from '../consent/buildConsentSourceConfig'\nimport type { ConsentSourceRegistry } from '../consent/registry'\nimport { keys } from '../translations/keys'\nimport { labelFor } from '../translations/server'\nimport { buildRuleBlocks } from '../validation/buildRuleBlocks'\nimport type { ValidationRuleRegistry } from '../validation/registry'\nimport type { FieldTypeRegistry } from './registry'\nimport { fieldBlockTabs } from './sharedConfig'\n\n/** The tab whose fields hold the shared basics and type config, found by the `name` field it carries. */\nconst fieldTabOf = (block: Block): Field[] | undefined => {\n\tconst tabsField = block.fields.find((f): f is TabsField => f.type === 'tabs')\n\treturn tabsField?.tabs.find((tab) => tab.fields
|
|
1
|
+
{"version":3,"file":"buildFieldBlocks.js","names":[],"sources":["../../src/fields/buildFieldBlocks.ts"],"sourcesContent":["import type { Block, Field, TabsField } from 'payload'\nimport { buildConditionTypeMap } from '../conditions/conditionType'\nimport { buildConsentSourceConfig } from '../consent/buildConsentSourceConfig'\nimport type { ConsentSourceRegistry } from '../consent/registry'\nimport { keys } from '../translations/keys'\nimport { labelFor } from '../translations/server'\nimport { buildRuleBlocks } from '../validation/buildRuleBlocks'\nimport type { ValidationRuleRegistry } from '../validation/registry'\nimport type { FieldTypeRegistry } from './registry'\nimport { fieldBlockTabs } from './sharedConfig'\n\n/** Whether `fields` contains a field named `name`, descending into presentational rows. */\nconst hasNameField = (fields: Field[]): boolean =>\n\tfields.some((f) => {\n\t\tif ('name' in f && f.name === 'name') {\n\t\t\treturn true\n\t\t}\n\t\treturn f.type === 'row' && hasNameField(f.fields)\n\t})\n\n/** The tab whose fields hold the shared basics and type config, found by the `name` field it carries. */\nconst fieldTabOf = (block: Block): Field[] | undefined => {\n\tconst tabsField = block.fields.find((f): f is TabsField => f.type === 'tabs')\n\treturn tabsField?.tabs.find((tab) => hasNameField(tab.fields))?.fields\n}\n\n/**\n * One add-field block per registered type: tabs holding shared config, type config, and\n * validations. `localize` controls whether the shared content fields carry `localized: true`;\n * per-type config fields carry their own flag from the registry definitions.\n */\ntype BuildFieldBlocksArgs = {\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\tconsentRegistry?: ConsentSourceRegistry\n\tlocalize?: boolean\n}\n\nexport const buildFieldBlocks = ({\n\tregistry,\n\truleRegistry,\n\tconsentRegistry,\n\tlocalize = true,\n}: BuildFieldBlocksArgs): Block[] => {\n\tconst conditionTypes = buildConditionTypeMap(registry)\n\tconst blocks: Block[] = []\n\tfor (const definition of registry.values()) {\n\t\tlet typeConfig: Field[] = definition.config ?? []\n\n\t\t// Inject dynamic source select + conditional sourceConfig group for the consent field.\n\t\t// consent.ts intentionally omits source/sourceConfig; the live registry drives the\n\t\t// select options and per-source field visibility (admin.condition).\n\t\tif (definition.type === 'consent' && consentRegistry) {\n\t\t\t// statement is first; optional is last; source/sourceConfig go in between.\n\t\t\tconst statement = typeConfig.find((f) => (f as { name?: string }).name === 'statement')\n\t\t\tconst optional = typeConfig.find((f) => (f as { name?: string }).name === 'optional')\n\t\t\ttypeConfig = [\n\t\t\t\t...(statement ? [statement] : []),\n\t\t\t\t...buildConsentSourceConfig(consentRegistry),\n\t\t\t\t...(optional ? [optional] : []),\n\t\t\t]\n\t\t}\n\n\t\tblocks.push({\n\t\t\tslug: definition.type,\n\t\t\tlabels: { singular: labelFor(definition.label), plural: labelFor(definition.label) },\n\t\t\tfields: [\n\t\t\t\tfieldBlockTabs({\n\t\t\t\t\tconditionTypes,\n\t\t\t\t\ttypeConfig,\n\t\t\t\t\tvalidations: {\n\t\t\t\t\t\tname: 'validations',\n\t\t\t\t\t\ttype: 'blocks',\n\t\t\t\t\t\tlabel: labelFor(keys.validationsLabel),\n\t\t\t\t\t\tblocks: buildRuleBlocks(ruleRegistry, definition.type),\n\t\t\t\t\t},\n\t\t\t\t\tlocalize,\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\t// Second pass: inject subFields into the repeater block using all non-repeater blocks.\n\t// Done after the main loop so every sibling block is already built.\n\t// Repeater-in-repeater is not supported in v1; the repeater block is excluded from subFields.\n\tconst repeaterBlock = blocks.find((b) => b.slug === 'repeater')\n\tif (repeaterBlock) {\n\t\tconst subFieldsField: Field = {\n\t\t\tname: 'subFields',\n\t\t\ttype: 'blocks',\n\t\t\tlabel: labelFor(keys.configSubFields),\n\t\t\tblocks: blocks.filter((b) => b.slug !== 'repeater'),\n\t\t}\n\t\tconst fieldTabFields = fieldTabOf(repeaterBlock)\n\t\t;(fieldTabFields ?? (repeaterBlock.fields as Field[])).push(subFieldsField)\n\t}\n\n\treturn blocks\n}\n"],"mappings":";;;;;;;;AAYA,MAAM,gBAAgB,WACrB,OAAO,MAAM,MAAM;CAClB,IAAI,UAAU,KAAK,EAAE,SAAS,QAC7B,OAAO;CAER,OAAO,EAAE,SAAS,SAAS,aAAa,EAAE,MAAM;AACjD,CAAC;;AAGF,MAAM,cAAc,UAAsC;CAEzD,OADkB,MAAM,OAAO,MAAM,MAAsB,EAAE,SAAS,MACvD,GAAG,KAAK,MAAM,QAAQ,aAAa,IAAI,MAAM,CAAC,GAAG;AACjE;AAcA,MAAa,oBAAoB,EAChC,UACA,cACA,iBACA,WAAW,WACyB;CACpC,MAAM,iBAAiB,sBAAsB,QAAQ;CACrD,MAAM,SAAkB,CAAC;CACzB,KAAK,MAAM,cAAc,SAAS,OAAO,GAAG;EAC3C,IAAI,aAAsB,WAAW,UAAU,CAAC;EAKhD,IAAI,WAAW,SAAS,aAAa,iBAAiB;GAErD,MAAM,YAAY,WAAW,MAAM,MAAO,EAAwB,SAAS,WAAW;GACtF,MAAM,WAAW,WAAW,MAAM,MAAO,EAAwB,SAAS,UAAU;GACpF,aAAa;IACZ,GAAI,YAAY,CAAC,SAAS,IAAI,CAAC;IAC/B,GAAG,yBAAyB,eAAe;IAC3C,GAAI,WAAW,CAAC,QAAQ,IAAI,CAAC;GAC9B;EACD;EAEA,OAAO,KAAK;GACX,MAAM,WAAW;GACjB,QAAQ;IAAE,UAAU,SAAS,WAAW,KAAK;IAAG,QAAQ,SAAS,WAAW,KAAK;GAAE;GACnF,QAAQ,CACP,eAAe;IACd;IACA;IACA,aAAa;KACZ,MAAM;KACN,MAAM;KACN,OAAO,SAAS,KAAK,gBAAgB;KACrC,QAAQ,gBAAgB,cAAc,WAAW,IAAI;IACtD;IACA;GACD,CAAC,CACF;EACD,CAAC;CACF;CAKA,MAAM,gBAAgB,OAAO,MAAM,MAAM,EAAE,SAAS,UAAU;CAC9D,IAAI,eAAe;EAClB,MAAM,iBAAwB;GAC7B,MAAM;GACN,MAAM;GACN,OAAO,SAAS,KAAK,eAAe;GACpC,QAAQ,OAAO,QAAQ,MAAM,EAAE,SAAS,UAAU;EACnD;EAEC,CADsB,WAAW,aACnB,KAAM,cAAc,QAAoB,KAAK,cAAc;CAC3E;CAEA,OAAO;AACR"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { localizedIf } from "../localizedIf.js";
|
|
1
2
|
import { keys } from "../../translations/keys.js";
|
|
2
3
|
import { labelFor } from "../../translations/server.js";
|
|
3
4
|
import { defineFormField } from "../defineFormField.js";
|
|
@@ -5,16 +6,18 @@ import { defineFormField } from "../defineFormField.js";
|
|
|
5
6
|
/**
|
|
6
7
|
* Base consent field definition. `source` select and `sourceConfig` group are injected
|
|
7
8
|
* by `buildFieldBlocks` from the live `consentRegistry`, so only the selected source's
|
|
8
|
-
* fields are visible in the admin UI via `admin.condition`.
|
|
9
|
+
* fields are visible in the admin UI via `admin.condition`. The `statement` is
|
|
10
|
+
* author-facing content and follows `localize`.
|
|
9
11
|
*/
|
|
10
|
-
const
|
|
12
|
+
const buildConsentField = (localize) => defineFormField({
|
|
11
13
|
type: "consent",
|
|
12
14
|
label: keys.fieldTypeConsent,
|
|
13
15
|
value: "boolean",
|
|
14
16
|
config: [{
|
|
15
17
|
name: "statement",
|
|
16
18
|
type: "text",
|
|
17
|
-
label: labelFor(keys.consentConfigStatement)
|
|
19
|
+
label: labelFor(keys.consentConfigStatement),
|
|
20
|
+
...localizedIf(localize)
|
|
18
21
|
}, {
|
|
19
22
|
name: "optional",
|
|
20
23
|
type: "checkbox",
|
|
@@ -26,7 +29,8 @@ const consentField = defineFormField({
|
|
|
26
29
|
},
|
|
27
30
|
format: ({ value, t }) => t(value === true ? keys.formatYes : keys.formatNo)
|
|
28
31
|
});
|
|
32
|
+
buildConsentField(true);
|
|
29
33
|
//#endregion
|
|
30
|
-
export {
|
|
34
|
+
export { buildConsentField };
|
|
31
35
|
|
|
32
36
|
//# sourceMappingURL=consent.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consent.js","names":[],"sources":["../../../src/fields/builtin/consent.ts"],"sourcesContent":["import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineFormField } from '../defineFormField'\n\ntype ConsentConfig = {\n\tstatement?: string\n\tsource?: string\n\tsourceConfig?: Record<string, unknown>\n\toptional?: boolean\n}\n\n/**\n * Base consent field definition. `source` select and `sourceConfig` group are injected\n * by `buildFieldBlocks` from the live `consentRegistry`, so only the selected source's\n * fields are visible in the admin UI via `admin.condition`.\n */\nexport const
|
|
1
|
+
{"version":3,"file":"consent.js","names":[],"sources":["../../../src/fields/builtin/consent.ts"],"sourcesContent":["import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineFormField } from '../defineFormField'\nimport { localizedIf } from '../localizedIf'\n\ntype ConsentConfig = {\n\tstatement?: string\n\tsource?: string\n\tsourceConfig?: Record<string, unknown>\n\toptional?: boolean\n}\n\n/**\n * Base consent field definition. `source` select and `sourceConfig` group are injected\n * by `buildFieldBlocks` from the live `consentRegistry`, so only the selected source's\n * fields are visible in the admin UI via `admin.condition`. The `statement` is\n * author-facing content and follows `localize`.\n */\nexport const buildConsentField = (localize: boolean) =>\n\tdefineFormField<'boolean', ConsentConfig>({\n\t\ttype: 'consent',\n\t\tlabel: keys.fieldTypeConsent,\n\t\tvalue: 'boolean',\n\t\tconfig: [\n\t\t\t{\n\t\t\t\tname: 'statement',\n\t\t\t\ttype: 'text',\n\t\t\t\tlabel: labelFor(keys.consentConfigStatement),\n\t\t\t\t...localizedIf(localize),\n\t\t\t},\n\t\t\t// source select and sourceConfig group are injected by buildFieldBlocks at plugin boot\n\t\t\t// so the options reflect the live consentRegistry rather than this static list.\n\t\t\t{ name: 'optional', type: 'checkbox', label: labelFor(keys.consentConfigOptional) },\n\t\t],\n\t\tvalidate: ({ value, config, t }) => {\n\t\t\tconst optional = (config as ConsentConfig).optional === true\n\t\t\tif (!optional && value !== true) {\n\t\t\t\treturn t(keys.validationRequired)\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\t\tformat: ({ value, t }) => t(value === true ? keys.formatYes : keys.formatNo),\n\t})\n\nexport const consentField = buildConsentField(true)\n"],"mappings":";;;;;;;;;;;AAkBA,MAAa,qBAAqB,aACjC,gBAA0C;CACzC,MAAM;CACN,OAAO,KAAK;CACZ,OAAO;CACP,QAAQ,CACP;EACC,MAAM;EACN,MAAM;EACN,OAAO,SAAS,KAAK,sBAAsB;EAC3C,GAAG,YAAY,QAAQ;CACxB,GAGA;EAAE,MAAM;EAAY,MAAM;EAAY,OAAO,SAAS,KAAK,qBAAqB;CAAE,CACnF;CACA,WAAW,EAAE,OAAO,QAAQ,QAAQ;EAEnC,IAAI,EADc,OAAyB,aAAa,SACvC,UAAU,MAC1B,OAAO,EAAE,KAAK,kBAAkB;EAEjC,OAAO;CACR;CACA,SAAS,EAAE,OAAO,QAAQ,EAAE,UAAU,OAAO,KAAK,YAAY,KAAK,QAAQ;AAC5E,CAAC;AAE0B,kBAAkB,IAAI"}
|
|
@@ -77,8 +77,12 @@ const fileMimeTypeOptions = [
|
|
|
77
77
|
* The `file` field type. Its stored value is a server-captured {@link FileRef}; the client only ever submits
|
|
78
78
|
* the upload id, and `runSubmission` re-reads filename/mimeType/filesize from the upload doc at the trust
|
|
79
79
|
* boundary (see `captureFileRef`). The intrinsic validator is intentionally a no-op: MIME/size/existence are
|
|
80
|
-
* enforced authoritatively server-side against the stored doc, never against client metadata. `
|
|
81
|
-
*
|
|
80
|
+
* enforced authoritatively server-side against the stored doc, never against client metadata. `mimeTypes`
|
|
81
|
+
* and `maxSize` persist on the block so the capture can enforce them. `uploadsCollection` is not
|
|
82
|
+
* author-editable: a forms hook stamps the plugin-configured uploads collection slug onto it on every save
|
|
83
|
+
* so the client renderer knows where to POST; the server never trusts it at submit time (plugin config
|
|
84
|
+
* stays the source of truth). Named `uploadsCollection` because `collection` is a mongoose-reserved
|
|
85
|
+
* schema pathname.
|
|
82
86
|
*/
|
|
83
87
|
const fileField = defineFormField({
|
|
84
88
|
type: "file",
|
|
@@ -86,9 +90,9 @@ const fileField = defineFormField({
|
|
|
86
90
|
value: "file",
|
|
87
91
|
config: [
|
|
88
92
|
{
|
|
89
|
-
name: "
|
|
93
|
+
name: "uploadsCollection",
|
|
90
94
|
type: "text",
|
|
91
|
-
|
|
95
|
+
admin: { hidden: true }
|
|
92
96
|
},
|
|
93
97
|
{
|
|
94
98
|
name: "mimeTypes",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.js","names":[],"sources":["../../../src/fields/builtin/file.ts"],"sourcesContent":["import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport type { FileRef } from '../../uploads/types'\nimport { defineFormField } from '../defineFormField'\n\ntype FileConfig = {\n\
|
|
1
|
+
{"version":3,"file":"file.js","names":[],"sources":["../../../src/fields/builtin/file.ts"],"sourcesContent":["import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport type { FileRef } from '../../uploads/types'\nimport { defineFormField } from '../defineFormField'\n\ntype FileConfig = {\n\tuploadsCollection?: string\n\tmimeTypes?: string[]\n\tmaxSize?: number\n}\n\nconst isFileRef = (value: unknown): value is FileRef =>\n\ttypeof value === 'object' && value !== null && 'filename' in value\n\nconst MAX_SIZE_REF = '@10x-media/form-builder/client#ByteSizeField'\n\n/**\n * Curated MIME type choices for the file field's `mimeTypes` select. Values are raw MIME strings or\n * trailing-`*` prefix wildcards, exactly the patterns `resolveFileRef` matches server-side; `type/*`\n * values double as the file input's `accept` attribute (browsers ignore other prefix patterns, which\n * is fine since the server stays authoritative). Every value must be 63 bytes or less: Payload's\n * db-postgres adapter stores select options as a pg enum, and pg enum labels cap at 63 bytes.\n */\nexport const fileMimeTypeOptions = [\n\t{ label: 'Any image', value: 'image/*' },\n\t{ label: 'PNG image', value: 'image/png' },\n\t{ label: 'JPEG image', value: 'image/jpeg' },\n\t{ label: 'WebP image', value: 'image/webp' },\n\t{ label: 'GIF image', value: 'image/gif' },\n\t{ label: 'SVG image', value: 'image/svg+xml' },\n\t{ label: 'PDF', value: 'application/pdf' },\n\t{ label: 'Plain text', value: 'text/plain' },\n\t{ label: 'CSV', value: 'text/csv' },\n\t{ label: 'ZIP archive', value: 'application/zip' },\n\t{ label: 'Word document (.doc)', value: 'application/msword' },\n\t{ label: 'Excel spreadsheet (.xls)', value: 'application/vnd.ms-excel' },\n\t{\n\t\tlabel: 'Office documents (docx, xlsx, pptx)',\n\t\tvalue: 'application/vnd.openxmlformats-officedocument.*',\n\t},\n\t{ label: 'Any audio', value: 'audio/*' },\n\t{ label: 'Any video', value: 'video/*' },\n]\n\n/**\n * The `file` field type. Its stored value is a server-captured {@link FileRef}; the client only ever submits\n * the upload id, and `runSubmission` re-reads filename/mimeType/filesize from the upload doc at the trust\n * boundary (see `captureFileRef`). The intrinsic validator is intentionally a no-op: MIME/size/existence are\n * enforced authoritatively server-side against the stored doc, never against client metadata. `mimeTypes`\n * and `maxSize` persist on the block so the capture can enforce them. `uploadsCollection` is not\n * author-editable: a forms hook stamps the plugin-configured uploads collection slug onto it on every save\n * so the client renderer knows where to POST; the server never trusts it at submit time (plugin config\n * stays the source of truth). Named `uploadsCollection` because `collection` is a mongoose-reserved\n * schema pathname.\n */\nexport const fileField = defineFormField<'file', FileConfig>({\n\ttype: 'file',\n\tlabel: keys.fieldTypeFile,\n\tvalue: 'file',\n\tconfig: [\n\t\t{ name: 'uploadsCollection', type: 'text', admin: { hidden: true } },\n\t\t{\n\t\t\tname: 'mimeTypes',\n\t\t\ttype: 'select',\n\t\t\thasMany: true,\n\t\t\toptions: fileMimeTypeOptions,\n\t\t\tlabel: labelFor(keys.fileConfigMimeTypes),\n\t\t},\n\t\t{\n\t\t\tname: 'maxSize',\n\t\t\ttype: 'number',\n\t\t\tmin: 0,\n\t\t\tlabel: labelFor(keys.fileConfigMaxSize),\n\t\t\tadmin: {\n\t\t\t\tdescription: labelFor(keys.fileConfigMaxSizeDescription),\n\t\t\t\tcomponents: { Field: MAX_SIZE_REF },\n\t\t\t},\n\t\t},\n\t],\n\tformat: ({ value }) => (isFileRef(value) ? value.filename : ''),\n})\n"],"mappings":";;;;AAWA,MAAM,aAAa,UAClB,OAAO,UAAU,YAAY,UAAU,QAAQ,cAAc;AAE9D,MAAM,eAAe;;;;;;;;AASrB,MAAa,sBAAsB;CAClC;EAAE,OAAO;EAAa,OAAO;CAAU;CACvC;EAAE,OAAO;EAAa,OAAO;CAAY;CACzC;EAAE,OAAO;EAAc,OAAO;CAAa;CAC3C;EAAE,OAAO;EAAc,OAAO;CAAa;CAC3C;EAAE,OAAO;EAAa,OAAO;CAAY;CACzC;EAAE,OAAO;EAAa,OAAO;CAAgB;CAC7C;EAAE,OAAO;EAAO,OAAO;CAAkB;CACzC;EAAE,OAAO;EAAc,OAAO;CAAa;CAC3C;EAAE,OAAO;EAAO,OAAO;CAAW;CAClC;EAAE,OAAO;EAAe,OAAO;CAAkB;CACjD;EAAE,OAAO;EAAwB,OAAO;CAAqB;CAC7D;EAAE,OAAO;EAA4B,OAAO;CAA2B;CACvE;EACC,OAAO;EACP,OAAO;CACR;CACA;EAAE,OAAO;EAAa,OAAO;CAAU;CACvC;EAAE,OAAO;EAAa,OAAO;CAAU;AACxC;;;;;;;;;;;;AAaA,MAAa,YAAY,gBAAoC;CAC5D,MAAM;CACN,OAAO,KAAK;CACZ,OAAO;CACP,QAAQ;EACP;GAAE,MAAM;GAAqB,MAAM;GAAQ,OAAO,EAAE,QAAQ,KAAK;EAAE;EACnE;GACC,MAAM;GACN,MAAM;GACN,SAAS;GACT,SAAS;GACT,OAAO,SAAS,KAAK,mBAAmB;EACzC;EACA;GACC,MAAM;GACN,MAAM;GACN,KAAK;GACL,OAAO,SAAS,KAAK,iBAAiB;GACtC,OAAO;IACN,aAAa,SAAS,KAAK,4BAA4B;IACvD,YAAY,EAAE,OAAO,aAAa;GACnC;EACD;CACD;CACA,SAAS,EAAE,YAAa,UAAU,KAAK,IAAI,MAAM,WAAW;AAC7D,CAAC"}
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
import { AnyFormFieldDefinition } from "../types.js";
|
|
2
2
|
|
|
3
3
|
//#region src/fields/builtin/index.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Built-in field definitions with content-bearing config fields (select option labels, consent
|
|
6
|
+
* statement, repeater add label) carrying `localized: true` when `localize` is true. Field types
|
|
7
|
+
* without content config are shared static definitions. Definitions are authored with precise
|
|
8
|
+
* value/config generics; the registry stores them erased (config is re-narrowed per matched type
|
|
9
|
+
* at execution), hence one cast per built-in, no `any`.
|
|
10
|
+
*/
|
|
11
|
+
declare const buildDefaultFieldDefinitions: (localize: boolean) => AnyFormFieldDefinition[];
|
|
4
12
|
declare const defaultFieldDefinitions: AnyFormFieldDefinition[];
|
|
5
13
|
/**
|
|
6
14
|
* `defaultFieldDefinitions` indexed by `type`, so a single built-in can be spread and tweaked
|
|
7
15
|
* without hand-rolling a `.find()`, e.g.
|
|
8
16
|
* `fields: { text: { ...defaultFieldDefinitionsByType.text, validate: myValidate } }`. The
|
|
9
17
|
* `fields` plugin option replaces a built-in of the same `type`; `false` removes it, `true` keeps it.
|
|
18
|
+
* Prebuilt with content localization on; with `localizeContent: false`, derive overrides from
|
|
19
|
+
* `buildDefaultFieldDefinitions(false)` instead so the spread does not reintroduce `localized`.
|
|
10
20
|
*/
|
|
11
21
|
declare const defaultFieldDefinitionsByType: Record<string, AnyFormFieldDefinition>;
|
|
12
22
|
//#endregion
|
|
13
|
-
export { defaultFieldDefinitions, defaultFieldDefinitionsByType };
|
|
23
|
+
export { buildDefaultFieldDefinitions, defaultFieldDefinitions, defaultFieldDefinitionsByType };
|
|
14
24
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,36 +1,48 @@
|
|
|
1
1
|
import { calculationField } from "./calculation.js";
|
|
2
2
|
import { checkboxField } from "./checkbox.js";
|
|
3
|
-
import {
|
|
3
|
+
import { buildConsentField } from "./consent.js";
|
|
4
4
|
import { dateField } from "./date.js";
|
|
5
5
|
import { emailField } from "./email.js";
|
|
6
6
|
import { fileField } from "./file.js";
|
|
7
|
+
import { buildMessageField } from "./message.js";
|
|
7
8
|
import { numberField } from "./number.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
9
|
+
import { buildRepeaterField } from "./repeater.js";
|
|
10
|
+
import { buildSelectField } from "./select.js";
|
|
10
11
|
import { textField } from "./text.js";
|
|
11
12
|
import { textareaField } from "./textarea.js";
|
|
12
13
|
//#region src/fields/builtin/index.ts
|
|
13
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Built-in field definitions with content-bearing config fields (select option labels, consent
|
|
16
|
+
* statement, repeater add label) carrying `localized: true` when `localize` is true. Field types
|
|
17
|
+
* without content config are shared static definitions. Definitions are authored with precise
|
|
18
|
+
* value/config generics; the registry stores them erased (config is re-narrowed per matched type
|
|
19
|
+
* at execution), hence one cast per built-in, no `any`.
|
|
20
|
+
*/
|
|
21
|
+
const buildDefaultFieldDefinitions = (localize) => [
|
|
14
22
|
textField,
|
|
15
23
|
textareaField,
|
|
16
24
|
emailField,
|
|
17
25
|
numberField,
|
|
18
|
-
|
|
26
|
+
buildSelectField(localize),
|
|
19
27
|
checkboxField,
|
|
20
28
|
calculationField,
|
|
21
|
-
|
|
29
|
+
buildConsentField(localize),
|
|
22
30
|
fileField,
|
|
23
|
-
|
|
24
|
-
dateField
|
|
31
|
+
buildRepeaterField(localize),
|
|
32
|
+
dateField,
|
|
33
|
+
buildMessageField(localize)
|
|
25
34
|
];
|
|
35
|
+
const defaultFieldDefinitions = buildDefaultFieldDefinitions(true);
|
|
26
36
|
/**
|
|
27
37
|
* `defaultFieldDefinitions` indexed by `type`, so a single built-in can be spread and tweaked
|
|
28
38
|
* without hand-rolling a `.find()`, e.g.
|
|
29
39
|
* `fields: { text: { ...defaultFieldDefinitionsByType.text, validate: myValidate } }`. The
|
|
30
40
|
* `fields` plugin option replaces a built-in of the same `type`; `false` removes it, `true` keeps it.
|
|
41
|
+
* Prebuilt with content localization on; with `localizeContent: false`, derive overrides from
|
|
42
|
+
* `buildDefaultFieldDefinitions(false)` instead so the spread does not reintroduce `localized`.
|
|
31
43
|
*/
|
|
32
44
|
const defaultFieldDefinitionsByType = Object.fromEntries(defaultFieldDefinitions.map((definition) => [definition.type, definition]));
|
|
33
45
|
//#endregion
|
|
34
|
-
export { defaultFieldDefinitions, defaultFieldDefinitionsByType };
|
|
46
|
+
export { buildDefaultFieldDefinitions, defaultFieldDefinitions, defaultFieldDefinitionsByType };
|
|
35
47
|
|
|
36
48
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/fields/builtin/index.ts"],"sourcesContent":["import type { AnyFormFieldDefinition } from '../types'\nimport { calculationField } from './calculation'\nimport { checkboxField } from './checkbox'\nimport {
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/fields/builtin/index.ts"],"sourcesContent":["import type { AnyFormFieldDefinition } from '../types'\nimport { calculationField } from './calculation'\nimport { checkboxField } from './checkbox'\nimport { buildConsentField } from './consent'\nimport { dateField } from './date'\nimport { emailField } from './email'\nimport { fileField } from './file'\nimport { buildMessageField } from './message'\nimport { numberField } from './number'\nimport { buildRepeaterField } from './repeater'\nimport { buildSelectField } from './select'\nimport { textField } from './text'\nimport { textareaField } from './textarea'\n\n/**\n * Built-in field definitions with content-bearing config fields (select option labels, consent\n * statement, repeater add label) carrying `localized: true` when `localize` is true. Field types\n * without content config are shared static definitions. Definitions are authored with precise\n * value/config generics; the registry stores them erased (config is re-narrowed per matched type\n * at execution), hence one cast per built-in, no `any`.\n */\nexport const buildDefaultFieldDefinitions = (localize: boolean): AnyFormFieldDefinition[] => [\n\ttextField as AnyFormFieldDefinition,\n\ttextareaField as AnyFormFieldDefinition,\n\temailField as AnyFormFieldDefinition,\n\tnumberField as AnyFormFieldDefinition,\n\tbuildSelectField(localize) as AnyFormFieldDefinition,\n\tcheckboxField as AnyFormFieldDefinition,\n\tcalculationField as AnyFormFieldDefinition,\n\tbuildConsentField(localize) as AnyFormFieldDefinition,\n\tfileField as AnyFormFieldDefinition,\n\tbuildRepeaterField(localize) as AnyFormFieldDefinition,\n\tdateField as AnyFormFieldDefinition,\n\tbuildMessageField(localize) as AnyFormFieldDefinition,\n]\n\nexport const defaultFieldDefinitions: AnyFormFieldDefinition[] = buildDefaultFieldDefinitions(true)\n\n/**\n * `defaultFieldDefinitions` indexed by `type`, so a single built-in can be spread and tweaked\n * without hand-rolling a `.find()`, e.g.\n * `fields: { text: { ...defaultFieldDefinitionsByType.text, validate: myValidate } }`. The\n * `fields` plugin option replaces a built-in of the same `type`; `false` removes it, `true` keeps it.\n * Prebuilt with content localization on; with `localizeContent: false`, derive overrides from\n * `buildDefaultFieldDefinitions(false)` instead so the spread does not reintroduce `localized`.\n */\nexport const defaultFieldDefinitionsByType: Record<string, AnyFormFieldDefinition> =\n\tObject.fromEntries(defaultFieldDefinitions.map((definition) => [definition.type, definition]))\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,gCAAgC,aAAgD;CAC5F;CACA;CACA;CACA;CACA,iBAAiB,QAAQ;CACzB;CACA;CACA,kBAAkB,QAAQ;CAC1B;CACA,mBAAmB,QAAQ;CAC3B;CACA,kBAAkB,QAAQ;AAC3B;AAEA,MAAa,0BAAoD,6BAA6B,IAAI;;;;;;;;;AAUlG,MAAa,gCACZ,OAAO,YAAY,wBAAwB,KAAK,eAAe,CAAC,WAAW,MAAM,UAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { localizedIf } from "../localizedIf.js";
|
|
2
|
+
import { keys } from "../../translations/keys.js";
|
|
3
|
+
import { labelFor } from "../../translations/server.js";
|
|
4
|
+
import { defineFormField } from "../defineFormField.js";
|
|
5
|
+
//#region src/fields/builtin/message.ts
|
|
6
|
+
/**
|
|
7
|
+
* Display-only inline rich text rendered between fields. Value kind `'none'`: the engine never
|
|
8
|
+
* validates it and never writes it to submissions (its `name` exists only for block identity,
|
|
9
|
+
* conditions targeting, and React keys). `content` is authored copy and follows `localize`.
|
|
10
|
+
*/
|
|
11
|
+
const buildMessageField = (localize) => defineFormField({
|
|
12
|
+
type: "message",
|
|
13
|
+
label: keys.fieldTypeMessage,
|
|
14
|
+
value: "none",
|
|
15
|
+
config: [{
|
|
16
|
+
name: "content",
|
|
17
|
+
type: "richText",
|
|
18
|
+
label: labelFor(keys.configContent),
|
|
19
|
+
...localizedIf(localize)
|
|
20
|
+
}]
|
|
21
|
+
});
|
|
22
|
+
buildMessageField(true);
|
|
23
|
+
//#endregion
|
|
24
|
+
export { buildMessageField };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.js","names":[],"sources":["../../../src/fields/builtin/message.ts"],"sourcesContent":["import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineFormField } from '../defineFormField'\nimport { localizedIf } from '../localizedIf'\n\n/**\n * Display-only inline rich text rendered between fields. Value kind `'none'`: the engine never\n * validates it and never writes it to submissions (its `name` exists only for block identity,\n * conditions targeting, and React keys). `content` is authored copy and follows `localize`.\n */\nexport const buildMessageField = (localize: boolean) =>\n\tdefineFormField<'none'>({\n\t\ttype: 'message',\n\t\tlabel: keys.fieldTypeMessage,\n\t\tvalue: 'none',\n\t\tconfig: [\n\t\t\t{\n\t\t\t\tname: 'content',\n\t\t\t\ttype: 'richText',\n\t\t\t\tlabel: labelFor(keys.configContent),\n\t\t\t\t...localizedIf(localize),\n\t\t\t},\n\t\t],\n\t})\n\nexport const messageField = buildMessageField(true)\n"],"mappings":";;;;;;;;;;AAUA,MAAa,qBAAqB,aACjC,gBAAwB;CACvB,MAAM;CACN,OAAO,KAAK;CACZ,OAAO;CACP,QAAQ,CACP;EACC,MAAM;EACN,MAAM;EACN,OAAO,SAAS,KAAK,aAAa;EAClC,GAAG,YAAY,QAAQ;CACxB,CACD;AACD,CAAC;AAE0B,kBAAkB,IAAI"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { localizedIf } from "../localizedIf.js";
|
|
1
2
|
import { keys } from "../../translations/keys.js";
|
|
2
3
|
import { labelFor } from "../../translations/server.js";
|
|
3
4
|
import { defineFormField } from "../defineFormField.js";
|
|
4
5
|
//#region src/fields/builtin/repeater.ts
|
|
5
|
-
|
|
6
|
+
/** `addLabel` is the visitor-facing add-row button text and follows `localize`; row bounds never do. */
|
|
7
|
+
const buildRepeaterField = (localize) => defineFormField({
|
|
6
8
|
type: "repeater",
|
|
7
9
|
label: keys.fieldTypeRepeater,
|
|
8
10
|
value: "repeater",
|
|
@@ -22,7 +24,8 @@ const repeaterField = defineFormField({
|
|
|
22
24
|
{
|
|
23
25
|
name: "addLabel",
|
|
24
26
|
type: "text",
|
|
25
|
-
label: labelFor(keys.configAddLabel)
|
|
27
|
+
label: labelFor(keys.configAddLabel),
|
|
28
|
+
...localizedIf(localize)
|
|
26
29
|
}
|
|
27
30
|
],
|
|
28
31
|
validate: ({ value, config, t }) => {
|
|
@@ -38,7 +41,8 @@ const repeaterField = defineFormField({
|
|
|
38
41
|
return t(keys.repeaterRowCount).replace("{count}", String(count));
|
|
39
42
|
}
|
|
40
43
|
});
|
|
44
|
+
buildRepeaterField(true);
|
|
41
45
|
//#endregion
|
|
42
|
-
export {
|
|
46
|
+
export { buildRepeaterField };
|
|
43
47
|
|
|
44
48
|
//# sourceMappingURL=repeater.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repeater.js","names":[],"sources":["../../../src/fields/builtin/repeater.ts"],"sourcesContent":["import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineFormField } from '../defineFormField'\n\ntype RepeaterConfig = {\n\tminRows?: number\n\tmaxRows?: number\n\taddLabel?: string\n}\n\nexport const
|
|
1
|
+
{"version":3,"file":"repeater.js","names":[],"sources":["../../../src/fields/builtin/repeater.ts"],"sourcesContent":["import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineFormField } from '../defineFormField'\nimport { localizedIf } from '../localizedIf'\n\ntype RepeaterConfig = {\n\tminRows?: number\n\tmaxRows?: number\n\taddLabel?: string\n}\n\n/** `addLabel` is the visitor-facing add-row button text and follows `localize`; row bounds never do. */\nexport const buildRepeaterField = (localize: boolean) =>\n\tdefineFormField<'repeater', RepeaterConfig>({\n\t\ttype: 'repeater',\n\t\tlabel: keys.fieldTypeRepeater,\n\t\tvalue: 'repeater',\n\t\tconfig: [\n\t\t\t{\n\t\t\t\tname: 'minRows',\n\t\t\t\ttype: 'number',\n\t\t\t\tmin: 0,\n\t\t\t\tlabel: labelFor(keys.configMinRows),\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'maxRows',\n\t\t\t\ttype: 'number',\n\t\t\t\tmin: 1,\n\t\t\t\tlabel: labelFor(keys.configMaxRows),\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'addLabel',\n\t\t\t\ttype: 'text',\n\t\t\t\tlabel: labelFor(keys.configAddLabel),\n\t\t\t\t...localizedIf(localize),\n\t\t\t},\n\t\t\t// subFields blocks field is injected by buildFieldBlocks after the main loop,\n\t\t\t// so all non-repeater blocks are available and repeater-in-repeater is excluded.\n\t\t],\n\t\tvalidate: ({ value, config, t }) => {\n\t\t\tconst rows = Array.isArray(value) ? value : []\n\t\t\tconst min = typeof config.minRows === 'number' ? config.minRows : 0\n\t\t\tif (rows.length < min) {\n\t\t\t\treturn t(keys.validationRepeaterMin).replace('{min}', String(min))\n\t\t\t}\n\t\t\tconst max = typeof config.maxRows === 'number' ? config.maxRows : undefined\n\t\t\tif (max != null && rows.length > max) {\n\t\t\t\treturn t(keys.validationRepeaterMax).replace('{max}', String(max))\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\t\tformat: ({ value, t }) => {\n\t\t\tconst count = Array.isArray(value) ? value.length : 0\n\t\t\treturn t(keys.repeaterRowCount).replace('{count}', String(count))\n\t\t},\n\t})\n\nexport const repeaterField = buildRepeaterField(true)\n"],"mappings":";;;;;;AAYA,MAAa,sBAAsB,aAClC,gBAA4C;CAC3C,MAAM;CACN,OAAO,KAAK;CACZ,OAAO;CACP,QAAQ;EACP;GACC,MAAM;GACN,MAAM;GACN,KAAK;GACL,OAAO,SAAS,KAAK,aAAa;EACnC;EACA;GACC,MAAM;GACN,MAAM;GACN,KAAK;GACL,OAAO,SAAS,KAAK,aAAa;EACnC;EACA;GACC,MAAM;GACN,MAAM;GACN,OAAO,SAAS,KAAK,cAAc;GACnC,GAAG,YAAY,QAAQ;EACxB;CAGD;CACA,WAAW,EAAE,OAAO,QAAQ,QAAQ;EACnC,MAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;EAC7C,MAAM,MAAM,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;EAClE,IAAI,KAAK,SAAS,KACjB,OAAO,EAAE,KAAK,qBAAqB,EAAE,QAAQ,SAAS,OAAO,GAAG,CAAC;EAElE,MAAM,MAAM,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU,KAAA;EAClE,IAAI,OAAO,QAAQ,KAAK,SAAS,KAChC,OAAO,EAAE,KAAK,qBAAqB,EAAE,QAAQ,SAAS,OAAO,GAAG,CAAC;EAElE,OAAO;CACR;CACA,SAAS,EAAE,OAAO,QAAQ;EACzB,MAAM,QAAQ,MAAM,QAAQ,KAAK,IAAI,MAAM,SAAS;EACpD,OAAO,EAAE,KAAK,gBAAgB,EAAE,QAAQ,WAAW,OAAO,KAAK,CAAC;CACjE;AACD,CAAC;AAE2B,mBAAmB,IAAI"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { localizedIf } from "../localizedIf.js";
|
|
1
2
|
import { keys } from "../../translations/keys.js";
|
|
2
3
|
import { labelFor } from "../../translations/server.js";
|
|
3
4
|
import { defineFormField } from "../defineFormField.js";
|
|
4
5
|
//#region src/fields/builtin/select.ts
|
|
5
|
-
|
|
6
|
+
/** Option `label` is author-facing content and follows `localize`; `value` is an identifier and never does. */
|
|
7
|
+
const buildSelectField = (localize) => defineFormField({
|
|
6
8
|
type: "select",
|
|
7
9
|
label: keys.fieldTypeSelect,
|
|
8
10
|
value: "text",
|
|
@@ -19,7 +21,8 @@ const selectField = defineFormField({
|
|
|
19
21
|
name: "label",
|
|
20
22
|
type: "text",
|
|
21
23
|
required: true,
|
|
22
|
-
label: labelFor(keys.configOptionLabel)
|
|
24
|
+
label: labelFor(keys.configOptionLabel),
|
|
25
|
+
...localizedIf(localize)
|
|
23
26
|
}, {
|
|
24
27
|
name: "value",
|
|
25
28
|
type: "text",
|
|
@@ -38,7 +41,8 @@ const selectField = defineFormField({
|
|
|
38
41
|
return optionLabels?.[value] ?? String(value);
|
|
39
42
|
}
|
|
40
43
|
});
|
|
44
|
+
buildSelectField(true);
|
|
41
45
|
//#endregion
|
|
42
|
-
export {
|
|
46
|
+
export { buildSelectField };
|
|
43
47
|
|
|
44
48
|
//# sourceMappingURL=select.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","names":[],"sources":["../../../src/fields/builtin/select.ts"],"sourcesContent":["import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineFormField } from '../defineFormField'\n\ntype SelectOption = { label: string; value: string }\ntype SelectConfig = { options?: SelectOption[] }\n\nexport const
|
|
1
|
+
{"version":3,"file":"select.js","names":[],"sources":["../../../src/fields/builtin/select.ts"],"sourcesContent":["import { keys } from '../../translations/keys'\nimport { labelFor } from '../../translations/server'\nimport { defineFormField } from '../defineFormField'\nimport { localizedIf } from '../localizedIf'\n\ntype SelectOption = { label: string; value: string }\ntype SelectConfig = { options?: SelectOption[] }\n\n/** Option `label` is author-facing content and follows `localize`; `value` is an identifier and never does. */\nexport const buildSelectField = (localize: boolean) =>\n\tdefineFormField<'text', SelectConfig>({\n\t\ttype: 'select',\n\t\tlabel: keys.fieldTypeSelect,\n\t\tvalue: 'text',\n\t\tconditionType: 'select',\n\t\tconfig: [\n\t\t\t{\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'array',\n\t\t\t\tlabel: labelFor(keys.configOptions),\n\t\t\t\tlabels: { singular: labelFor(keys.configOption), plural: labelFor(keys.configOptions) },\n\t\t\t\tfields: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'label',\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\tlabel: labelFor(keys.configOptionLabel),\n\t\t\t\t\t\t...localizedIf(localize),\n\t\t\t\t\t},\n\t\t\t\t\t{ name: 'value', type: 'text', required: true, label: labelFor(keys.configOptionValue) },\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t\tvalidate: ({ value, config, t }) => {\n\t\t\tif (value == null || value === '') {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tconst options = config.options ?? []\n\t\t\tif (options.length === 0) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn options.some((option) => option.value === value) ? true : t(keys.validationSelect)\n\t\t},\n\t\tformat: ({ value, optionLabels }) => {\n\t\t\tif (value == null || value === '') {\n\t\t\t\treturn ''\n\t\t\t}\n\t\t\treturn optionLabels?.[value] ?? String(value)\n\t\t},\n\t})\n\nexport const selectField = buildSelectField(true)\n"],"mappings":";;;;;;AASA,MAAa,oBAAoB,aAChC,gBAAsC;CACrC,MAAM;CACN,OAAO,KAAK;CACZ,OAAO;CACP,eAAe;CACf,QAAQ,CACP;EACC,MAAM;EACN,MAAM;EACN,OAAO,SAAS,KAAK,aAAa;EAClC,QAAQ;GAAE,UAAU,SAAS,KAAK,YAAY;GAAG,QAAQ,SAAS,KAAK,aAAa;EAAE;EACtF,QAAQ,CACP;GACC,MAAM;GACN,MAAM;GACN,UAAU;GACV,OAAO,SAAS,KAAK,iBAAiB;GACtC,GAAG,YAAY,QAAQ;EACxB,GACA;GAAE,MAAM;GAAS,MAAM;GAAQ,UAAU;GAAM,OAAO,SAAS,KAAK,iBAAiB;EAAE,CACxF;CACD,CACD;CACA,WAAW,EAAE,OAAO,QAAQ,QAAQ;EACnC,IAAI,SAAS,QAAQ,UAAU,IAC9B,OAAO;EAER,MAAM,UAAU,OAAO,WAAW,CAAC;EACnC,IAAI,QAAQ,WAAW,GACtB,OAAO;EAER,OAAO,QAAQ,MAAM,WAAW,OAAO,UAAU,KAAK,IAAI,OAAO,EAAE,KAAK,gBAAgB;CACzF;CACA,SAAS,EAAE,OAAO,mBAAmB;EACpC,IAAI,SAAS,QAAQ,UAAU,IAC9B,OAAO;EAER,OAAO,eAAe,UAAU,OAAO,KAAK;CAC7C;AACD,CAAC;AAEyB,iBAAiB,IAAI"}
|