@10x-media/form-builder 0.1.0-beta.0 → 0.1.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +345 -0
- package/README.md +45 -1402
- package/dist/actions/body/converters.d.ts +20 -0
- package/dist/actions/body/converters.js +57 -0
- package/dist/actions/body/converters.js.map +1 -0
- package/dist/actions/body/escapeHtml.d.ts +6 -0
- package/dist/actions/body/escapeHtml.js +14 -0
- package/dist/actions/body/escapeHtml.js.map +1 -0
- package/dist/actions/body/serializeBody.d.ts +55 -0
- package/dist/actions/body/serializeBody.js +78 -0
- package/dist/actions/body/serializeBody.js.map +1 -0
- package/dist/actions/body/serializeSlate.js +31 -0
- package/dist/actions/body/serializeSlate.js.map +1 -0
- package/dist/actions/body/textOfBody.d.ts +13 -0
- package/dist/actions/body/textOfBody.js +35 -0
- package/dist/actions/body/textOfBody.js.map +1 -0
- package/dist/actions/body/wildcards.d.ts +10 -0
- package/dist/actions/body/wildcards.js +33 -0
- package/dist/actions/body/wildcards.js.map +1 -0
- package/dist/actions/buildActionBlocks.js +22 -0
- package/dist/actions/buildActionBlocks.js.map +1 -0
- package/dist/actions/builtin/confirmation.js +52 -0
- package/dist/actions/builtin/confirmation.js.map +1 -0
- package/dist/actions/builtin/emailAction.d.ts +17 -0
- package/dist/actions/builtin/emailAction.js +83 -0
- package/dist/actions/builtin/emailAction.js.map +1 -0
- package/dist/actions/builtin/emailTeam.js +22 -0
- package/dist/actions/builtin/emailTeam.js.map +1 -0
- package/dist/actions/builtin/index.d.ts +22 -0
- package/dist/actions/builtin/index.js +27 -0
- package/dist/actions/builtin/index.js.map +1 -0
- package/dist/actions/builtin/signedWebhook.js +53 -0
- package/dist/actions/builtin/signedWebhook.js.map +1 -0
- package/dist/actions/defineAction.d.ts +37 -0
- package/dist/actions/defineAction.js +6 -0
- package/dist/actions/defineAction.js.map +1 -0
- package/dist/actions/dispatch.js +49 -0
- package/dist/actions/dispatch.js.map +1 -0
- package/dist/actions/emailRecipients.d.ts +12 -0
- package/dist/actions/emailRecipients.js +116 -0
- package/dist/actions/emailRecipients.js.map +1 -0
- package/dist/actions/fromAddresses.d.ts +21 -0
- package/dist/actions/fromAddresses.js +74 -0
- package/dist/actions/fromAddresses.js.map +1 -0
- package/dist/actions/registry.d.ts +17 -0
- package/dist/actions/registry.js +12 -0
- package/dist/actions/registry.js.map +1 -0
- package/dist/actions/runActions.d.ts +9 -0
- package/dist/actions/runActions.js +43 -0
- package/dist/actions/runActions.js.map +1 -0
- package/dist/actions/sign.d.ts +7 -0
- package/dist/actions/sign.js +9 -0
- package/dist/actions/sign.js.map +1 -0
- package/dist/actions/task.js +87 -0
- package/dist/actions/task.js.map +1 -0
- package/dist/aggregation/aggregateResponses.d.ts +40 -0
- package/dist/aggregation/aggregateResponses.js +80 -0
- package/dist/aggregation/aggregateResponses.js.map +1 -0
- package/dist/aggregation/aggregateRows.d.ts +10 -0
- package/dist/aggregation/aggregateRows.js +64 -0
- package/dist/aggregation/aggregateRows.js.map +1 -0
- package/dist/aggregation/resolveResultsRequest.d.ts +61 -0
- package/dist/aggregation/resolveResultsRequest.js +113 -0
- package/dist/aggregation/resolveResultsRequest.js.map +1 -0
- package/dist/aggregation/types.d.ts +39 -0
- package/dist/calc/computeCalcFields.d.ts +15 -0
- package/dist/calc/computeCalcFields.js +28 -0
- package/dist/calc/computeCalcFields.js.map +1 -0
- package/dist/calc/evaluate.d.ts +8 -0
- package/dist/calc/evaluate.js +58 -0
- package/dist/calc/evaluate.js.map +1 -0
- package/dist/calc/normalizeCalc.d.ts +8 -0
- package/dist/calc/normalizeCalc.js +87 -0
- package/dist/calc/normalizeCalc.js.map +1 -0
- package/dist/calc/types.d.ts +34 -0
- package/dist/calc/types.js +22 -0
- package/dist/calc/types.js.map +1 -0
- package/dist/client/ByteSizeField.d.ts +29 -0
- package/dist/client/ByteSizeField.js +58 -0
- package/dist/client/ByteSizeField.js.map +1 -0
- package/dist/client/ClosePollButton.d.ts +15 -0
- package/dist/client/ClosePollButton.js +80 -0
- package/dist/client/ClosePollButton.js.map +1 -0
- package/dist/client/CondensedArray.d.ts +15 -0
- package/dist/client/CondensedArray.js +97 -0
- package/dist/client/CondensedArray.js.map +1 -0
- package/dist/client/ConditionBuilder.js +122 -0
- package/dist/client/ConditionBuilder.js.map +1 -0
- package/dist/client/ConditionRow.js +150 -0
- package/dist/client/ConditionRow.js.map +1 -0
- package/dist/client/ConsentBlockLabel.d.ts +15 -0
- package/dist/client/ConsentBlockLabel.js +71 -0
- package/dist/client/ConsentBlockLabel.js.map +1 -0
- package/dist/client/ConsentSourceRowLabel.d.ts +9 -0
- package/dist/client/ConsentSourceRowLabel.js +21 -0
- package/dist/client/ConsentSourceRowLabel.js.map +1 -0
- package/dist/client/EndpointOptionsSelect.d.ts +46 -0
- package/dist/client/EndpointOptionsSelect.js +106 -0
- package/dist/client/EndpointOptionsSelect.js.map +1 -0
- package/dist/client/FieldBlockLabel.d.ts +18 -0
- package/dist/client/FieldBlockLabel.js +34 -0
- package/dist/client/FieldBlockLabel.js.map +1 -0
- package/dist/client/FieldNameSelect.d.ts +37 -0
- package/dist/client/FieldNameSelect.js +72 -0
- package/dist/client/FieldNameSelect.js.map +1 -0
- package/dist/client/FlowBuilder.d.ts +15 -0
- package/dist/client/FlowBuilder.js +457 -0
- package/dist/client/FlowBuilder.js.map +1 -0
- package/dist/client/FormConditionField.d.ts +21 -0
- package/dist/client/FormConditionField.js +30 -0
- package/dist/client/FormConditionField.js.map +1 -0
- package/dist/client/RecipientsSelect.d.ts +31 -0
- package/dist/client/RecipientsSelect.js +174 -0
- package/dist/client/RecipientsSelect.js.map +1 -0
- package/dist/client/RuleDescription.d.ts +21 -0
- package/dist/client/RuleDescription.js +19 -0
- package/dist/client/RuleDescription.js.map +1 -0
- package/dist/client/admin.css +275 -0
- package/dist/client/endpointOptions.js +29 -0
- package/dist/client/endpointOptions.js.map +1 -0
- package/dist/client/flowAuthoring.js +142 -0
- package/dist/client/flowAuthoring.js.map +1 -0
- package/dist/client/synthesizeClientField.js +57 -0
- package/dist/client/synthesizeClientField.js.map +1 -0
- package/dist/client/toStaticLabel.js +13 -0
- package/dist/client/toStaticLabel.js.map +1 -0
- package/dist/collections/buttonFields.d.ts +34 -0
- package/dist/collections/buttonFields.js +35 -0
- package/dist/collections/buttonFields.js.map +1 -0
- package/dist/collections/cells/FieldCountCell.d.ts +15 -0
- package/dist/collections/cells/FieldCountCell.js +18 -0
- package/dist/collections/cells/FieldCountCell.js.map +1 -0
- package/dist/collections/cells/FlowStepsCell.d.ts +14 -0
- package/dist/collections/cells/FlowStepsCell.js +17 -0
- package/dist/collections/cells/FlowStepsCell.js.map +1 -0
- package/dist/collections/formSubmissions.js +204 -0
- package/dist/collections/formSubmissions.js.map +1 -0
- package/dist/collections/forms.js +482 -0
- package/dist/collections/forms.js.map +1 -0
- package/dist/collections/formsEndpoints.js +101 -0
- package/dist/collections/formsEndpoints.js.map +1 -0
- package/dist/collections/redirectFields.d.ts +29 -0
- package/dist/conditions/conditionType.js +21 -0
- package/dist/conditions/conditionType.js.map +1 -0
- package/dist/conditions/evaluate.d.ts +17 -0
- package/dist/conditions/evaluate.js +94 -0
- package/dist/conditions/evaluate.js.map +1 -0
- package/dist/conditions/fieldTypes.d.ts +11 -0
- package/dist/{fieldTypes-CzhhJXjg.js → conditions/fieldTypes.js} +6 -3
- package/dist/conditions/fieldTypes.js.map +1 -0
- package/dist/conditions/normalizeConditions.js +61 -0
- package/dist/conditions/normalizeConditions.js.map +1 -0
- package/dist/conditions/types.d.ts +8 -0
- package/dist/consent/applyConsentStatements.d.ts +14 -0
- package/dist/consent/applyConsentStatements.js +17 -0
- package/dist/consent/applyConsentStatements.js.map +1 -0
- package/dist/consent/captureConsent.d.ts +55 -0
- package/dist/consent/captureConsent.js +73 -0
- package/dist/consent/captureConsent.js.map +1 -0
- package/dist/consent/consentSourcesField.d.ts +66 -0
- package/dist/consent/consentSourcesField.js +90 -0
- package/dist/consent/consentSourcesField.js.map +1 -0
- package/dist/consent/resolveConsentEntries.d.ts +24 -0
- package/dist/consent/resolveConsentEntries.js +40 -0
- package/dist/consent/resolveConsentEntries.js.map +1 -0
- package/dist/consent/resolveConsentSourcesRequest.d.ts +37 -0
- package/dist/consent/resolveConsentSourcesRequest.js +54 -0
- package/dist/consent/resolveConsentSourcesRequest.js.map +1 -0
- package/dist/consent/resolveConsentStatements.d.ts +45 -0
- package/dist/consent/resolveConsentStatements.js +44 -0
- package/dist/consent/resolveConsentStatements.js.map +1 -0
- package/dist/consent/resolvePublishedVersionRef.d.ts +23 -0
- package/dist/consent/resolvePublishedVersionRef.js +30 -0
- package/dist/consent/resolvePublishedVersionRef.js.map +1 -0
- package/dist/consent/types.d.ts +61 -0
- package/dist/email/departments.d.ts +59 -0
- package/dist/email/departments.js +87 -0
- package/dist/email/departments.js.map +1 -0
- package/dist/email/departmentsField.d.ts +53 -0
- package/dist/email/departmentsField.js +73 -0
- package/dist/email/departmentsField.js.map +1 -0
- package/dist/events/noopSink.js +6 -0
- package/dist/events/noopSink.js.map +1 -0
- package/dist/events/resolveEventSink.js +8 -0
- package/dist/events/resolveEventSink.js.map +1 -0
- package/dist/events/types.d.ts +31 -0
- package/dist/exports/client.d.ts +15 -21
- package/dist/exports/client.js +15 -319
- package/dist/exports/i18n.d.ts +6 -138
- package/dist/exports/i18n.js +6 -3
- package/dist/exports/react.d.ts +63 -550
- package/dist/exports/react.js +55 -1563
- package/dist/exports/rsc.d.ts +9 -16
- package/dist/exports/rsc.js +9 -55
- package/dist/exports/types.d.ts +36 -5
- package/dist/fields/buildFieldBlocks.js +80 -0
- package/dist/fields/buildFieldBlocks.js.map +1 -0
- package/dist/fields/builtin/calculation.js +144 -0
- package/dist/fields/builtin/calculation.js.map +1 -0
- package/dist/fields/builtin/checkbox.js +21 -0
- package/dist/fields/builtin/checkbox.js.map +1 -0
- package/dist/fields/builtin/consent.js +47 -0
- package/dist/fields/builtin/consent.js.map +1 -0
- package/dist/fields/builtin/country.d.ts +13 -0
- package/dist/fields/builtin/country.js +30 -0
- package/dist/fields/builtin/country.js.map +1 -0
- package/dist/fields/builtin/date.js +31 -0
- package/dist/fields/builtin/date.js.map +1 -0
- package/dist/fields/builtin/email.js +18 -0
- package/dist/fields/builtin/email.js.map +1 -0
- package/dist/fields/builtin/file.d.ts +15 -0
- package/dist/fields/builtin/file.js +127 -0
- package/dist/fields/builtin/file.js.map +1 -0
- package/dist/fields/builtin/index.d.ts +26 -0
- package/dist/fields/builtin/index.js +49 -0
- package/dist/fields/builtin/index.js.map +1 -0
- package/dist/fields/builtin/message.js +30 -0
- package/dist/fields/builtin/message.js.map +1 -0
- package/dist/fields/builtin/number.js +17 -0
- package/dist/fields/builtin/number.js.map +1 -0
- package/dist/fields/builtin/repeater.js +49 -0
- package/dist/fields/builtin/repeater.js.map +1 -0
- package/dist/fields/builtin/select.js +49 -0
- package/dist/fields/builtin/select.js.map +1 -0
- package/dist/fields/builtin/state.d.ts +13 -0
- package/dist/fields/builtin/state.js +30 -0
- package/dist/fields/builtin/state.js.map +1 -0
- package/dist/fields/builtin/text.js +13 -0
- package/dist/fields/builtin/text.js.map +1 -0
- package/dist/fields/builtin/textarea.js +13 -0
- package/dist/fields/builtin/textarea.js.map +1 -0
- package/dist/fields/data/regions.d.ts +21 -0
- package/dist/fields/data/regions.js +1238 -0
- package/dist/fields/data/regions.js.map +1 -0
- package/dist/fields/defineFormField.d.ts +13 -0
- package/dist/fields/defineFormField.js +12 -0
- package/dist/fields/defineFormField.js.map +1 -0
- package/dist/fields/fieldKey.d.ts +15 -0
- package/dist/fields/fieldKey.js +16 -0
- package/dist/fields/fieldKey.js.map +1 -0
- package/dist/fields/fieldNamesOfType.js +30 -0
- package/dist/fields/fieldNamesOfType.js.map +1 -0
- package/dist/fields/instanceOptions.js +20 -0
- package/dist/fields/instanceOptions.js.map +1 -0
- package/dist/fields/localizedIf.d.ts +13 -0
- package/dist/fields/localizedIf.js +12 -0
- package/dist/fields/localizedIf.js.map +1 -0
- package/dist/fields/registry.d.ts +12 -0
- package/dist/fields/registry.js +39 -0
- package/dist/fields/registry.js.map +1 -0
- package/dist/fields/sharedConfig.js +151 -0
- package/dist/fields/sharedConfig.js.map +1 -0
- package/dist/fields/types.d.ts +152 -0
- package/dist/flow/engine.d.ts +19 -0
- package/dist/flow/engine.js +29 -0
- package/dist/flow/engine.js.map +1 -0
- package/dist/flow/normalizeFlow.js +54 -0
- package/dist/flow/normalizeFlow.js.map +1 -0
- package/dist/flow/stepLabel.js +15 -0
- package/dist/flow/stepLabel.js.map +1 -0
- package/dist/flow/types.d.ts +32 -0
- package/dist/flow/types.js +11 -0
- package/dist/flow/types.js.map +1 -0
- package/dist/form/pollState.d.ts +22 -0
- package/dist/form/pollState.js +17 -0
- package/dist/form/pollState.js.map +1 -0
- package/dist/form/toFormDocument.d.ts +102 -0
- package/dist/form/toFormDocument.js +87 -0
- package/dist/form/toFormDocument.js.map +1 -0
- package/dist/form/types.d.ts +65 -0
- package/dist/index.d.ts +88 -4
- package/dist/index.js +111 -1898
- package/dist/index.js.map +1 -1
- package/dist/options.d.ts +229 -0
- package/dist/plugin/access.js +12 -0
- package/dist/plugin/access.js.map +1 -0
- package/dist/plugin/applyRegistryConfig.d.ts +11 -0
- package/dist/plugin/applyRegistryConfig.js +20 -0
- package/dist/plugin/applyRegistryConfig.js.map +1 -0
- package/dist/plugin/collectionOverrides.d.ts +22 -0
- package/dist/plugin/customState.js +26 -0
- package/dist/plugin/customState.js.map +1 -0
- package/dist/plugin/registerCollections.js +60 -0
- package/dist/plugin/registerCollections.js.map +1 -0
- package/dist/plugin/registerTranslations.js +19 -0
- package/dist/plugin/registerTranslations.js.map +1 -0
- package/dist/plugin/uploadsCollection.d.ts +16 -0
- package/dist/plugin/uploadsCollection.js +53 -0
- package/dist/plugin/uploadsCollection.js.map +1 -0
- package/dist/poll/applyPollOptions.js +18 -0
- package/dist/poll/applyPollOptions.js.map +1 -0
- package/dist/poll/buildPollOptionSourceFields.js +50 -0
- package/dist/poll/buildPollOptionSourceFields.js.map +1 -0
- package/dist/poll/closeJob.d.ts +52 -0
- package/dist/poll/closeJob.js +119 -0
- package/dist/poll/closeJob.js.map +1 -0
- package/dist/poll/definePollOptionSource.d.ts +44 -0
- package/dist/poll/definePollOptionSource.js +6 -0
- package/dist/poll/definePollOptionSource.js.map +1 -0
- package/dist/poll/definePollType.d.ts +34 -0
- package/dist/poll/definePollType.js +6 -0
- package/dist/poll/definePollType.js.map +1 -0
- package/dist/poll/effectivePollOptions.d.ts +38 -0
- package/dist/poll/effectivePollOptions.js +64 -0
- package/dist/poll/effectivePollOptions.js.map +1 -0
- package/dist/poll/mostVoted.d.ts +21 -0
- package/dist/poll/mostVoted.js +32 -0
- package/dist/poll/mostVoted.js.map +1 -0
- package/dist/poll/outcomeBeforeChange.js +91 -0
- package/dist/poll/outcomeBeforeChange.js.map +1 -0
- package/dist/poll/outcomeFields.d.ts +38 -0
- package/dist/poll/outcomeFields.js +52 -0
- package/dist/poll/outcomeFields.js.map +1 -0
- package/dist/poll/pollTypeRegistry.d.ts +34 -0
- package/dist/poll/pollTypeRegistry.js +69 -0
- package/dist/poll/pollTypeRegistry.js.map +1 -0
- package/dist/poll/registry.d.ts +17 -0
- package/dist/poll/registry.js +12 -0
- package/dist/poll/registry.js.map +1 -0
- package/dist/poll/resolvePollCloseRequest.js +105 -0
- package/dist/poll/resolvePollCloseRequest.js.map +1 -0
- package/dist/poll/resolvePollOptions.d.ts +29 -0
- package/dist/poll/resolvePollOptions.js +52 -0
- package/dist/poll/resolvePollOptions.js.map +1 -0
- package/dist/poll/resolvePollOptionsRequest.js +50 -0
- package/dist/poll/resolvePollOptionsRequest.js.map +1 -0
- package/dist/poll/resolvePollOutcome.d.ts +34 -0
- package/dist/poll/resolvePollOutcome.js +76 -0
- package/dist/poll/resolvePollOutcome.js.map +1 -0
- package/dist/poll/resultsField.js +21 -0
- package/dist/poll/resultsField.js.map +1 -0
- package/dist/prefill/valuesFromSearchParams.d.ts +18 -0
- package/dist/prefill/valuesFromSearchParams.js +41 -0
- package/dist/prefill/valuesFromSearchParams.js.map +1 -0
- package/dist/presentations/defaults.d.ts +33 -0
- package/dist/presentations/defaults.js +35 -0
- package/dist/presentations/defaults.js.map +1 -0
- package/dist/presentations/types.d.ts +19 -0
- package/dist/react/Form.d.ts +128 -0
- package/dist/react/Form.js +619 -0
- package/dist/react/Form.js.map +1 -0
- package/dist/react/FormContext.d.ts +59 -0
- package/dist/react/FormContext.js +14 -0
- package/dist/react/FormContext.js.map +1 -0
- package/dist/react/FormControls.d.ts +55 -0
- package/dist/react/FormControls.js +56 -0
- package/dist/react/FormControls.js.map +1 -0
- package/dist/react/FormFields.d.ts +18 -0
- package/dist/react/FormFields.js +114 -0
- package/dist/react/FormFields.js.map +1 -0
- package/dist/react/FormLayout.d.ts +22 -0
- package/dist/react/FormLayout.js +15 -0
- package/dist/react/FormLayout.js.map +1 -0
- package/dist/react/FormResults.d.ts +28 -0
- package/dist/react/FormResults.js +93 -0
- package/dist/react/FormResults.js.map +1 -0
- package/dist/react/FormSteps.d.ts +17 -0
- package/dist/react/FormSteps.js +35 -0
- package/dist/react/FormSteps.js.map +1 -0
- package/dist/react/Honeypot.d.ts +22 -0
- package/dist/react/Honeypot.js +38 -0
- package/dist/react/Honeypot.js.map +1 -0
- package/dist/react/Poll.d.ts +43 -0
- package/dist/react/Poll.js +135 -0
- package/dist/react/Poll.js.map +1 -0
- package/dist/react/captcha/HcaptchaCaptcha.d.ts +28 -0
- package/dist/react/captcha/HcaptchaCaptcha.js +53 -0
- package/dist/react/captcha/HcaptchaCaptcha.js.map +1 -0
- package/dist/react/captcha/RecaptchaCaptcha.d.ts +41 -0
- package/dist/react/captcha/RecaptchaCaptcha.js +93 -0
- package/dist/react/captcha/RecaptchaCaptcha.js.map +1 -0
- package/dist/react/captcha/TurnstileCaptcha.d.ts +28 -0
- package/dist/react/captcha/TurnstileCaptcha.js +53 -0
- package/dist/react/captcha/TurnstileCaptcha.js.map +1 -0
- package/dist/react/captcha/types.d.ts +8 -0
- package/dist/react/captcha/useCaptchaScript.js +45 -0
- package/dist/react/captcha/useCaptchaScript.js.map +1 -0
- package/dist/react/captcha/vendors.js +8 -0
- package/dist/react/captcha/vendors.js.map +1 -0
- package/dist/react/cn.d.ts +6 -0
- package/dist/react/cn.js +8 -0
- package/dist/react/cn.js.map +1 -0
- package/dist/react/contract.d.ts +31 -0
- package/dist/react/contract.js +7 -0
- package/dist/react/contract.js.map +1 -0
- package/dist/react/events.js +14 -0
- package/dist/react/events.js.map +1 -0
- package/dist/react/fetchResults.d.ts +25 -0
- package/dist/react/fetchResults.js +31 -0
- package/dist/react/fetchResults.js.map +1 -0
- package/dist/react/presentation/Backdrop.d.ts +18 -0
- package/dist/react/presentation/Backdrop.js +14 -0
- package/dist/react/presentation/Backdrop.js.map +1 -0
- package/dist/react/presentation/DialogSurface.d.ts +35 -0
- package/dist/react/presentation/DialogSurface.js +53 -0
- package/dist/react/presentation/DialogSurface.js.map +1 -0
- package/dist/react/presentation/presentations.d.ts +7 -0
- package/dist/react/presentation/presentations.js +32 -0
- package/dist/react/presentation/presentations.js.map +1 -0
- package/dist/react/presentation/registry.d.ts +11 -0
- package/dist/react/presentation/registry.js +12 -0
- package/dist/react/presentation/registry.js.map +1 -0
- package/dist/react/presentation/types.d.ts +19 -0
- package/dist/react/presentation/useDismiss.d.ts +19 -0
- package/dist/react/presentation/useDismiss.js +33 -0
- package/dist/react/presentation/useDismiss.js.map +1 -0
- package/dist/react/presentation/useFocusTrap.d.ts +8 -0
- package/dist/react/presentation/useFocusTrap.js +35 -0
- package/dist/react/presentation/useFocusTrap.js.map +1 -0
- package/dist/react/presentation/useScrollLock.d.ts +6 -0
- package/dist/react/presentation/useScrollLock.js +18 -0
- package/dist/react/presentation/useScrollLock.js.map +1 -0
- package/dist/react/primitives/Checkbox.d.ts +28 -0
- package/dist/react/primitives/Checkbox.js +21 -0
- package/dist/react/primitives/Checkbox.js.map +1 -0
- package/dist/react/primitives/FieldShell.d.ts +29 -0
- package/dist/react/primitives/FieldShell.js +44 -0
- package/dist/react/primitives/FieldShell.js.map +1 -0
- package/dist/react/primitives/Input.d.ts +30 -0
- package/dist/react/primitives/Input.js +21 -0
- package/dist/react/primitives/Input.js.map +1 -0
- package/dist/react/primitives/Select.d.ts +34 -0
- package/dist/react/primitives/Select.js +26 -0
- package/dist/react/primitives/Select.js.map +1 -0
- package/dist/react/primitives/Textarea.d.ts +28 -0
- package/dist/react/primitives/Textarea.js +20 -0
- package/dist/react/primitives/Textarea.js.map +1 -0
- package/dist/react/recall.js +20 -0
- package/dist/react/recall.js.map +1 -0
- package/dist/react/registry.d.ts +16 -0
- package/dist/react/registry.js +16 -0
- package/dist/react/registry.js.map +1 -0
- package/dist/react/renderers/calculation.js +27 -0
- package/dist/react/renderers/calculation.js.map +1 -0
- package/dist/react/renderers/checkbox.js +32 -0
- package/dist/react/renderers/checkbox.js.map +1 -0
- package/dist/react/renderers/consent.js +97 -0
- package/dist/react/renderers/consent.js.map +1 -0
- package/dist/react/renderers/date.js +33 -0
- package/dist/react/renderers/date.js.map +1 -0
- package/dist/react/renderers/email.js +34 -0
- package/dist/react/renderers/email.js.map +1 -0
- package/dist/react/renderers/file.js +107 -0
- package/dist/react/renderers/file.js.map +1 -0
- package/dist/react/renderers/index.d.ts +8 -0
- package/dist/react/renderers/index.js +35 -0
- package/dist/react/renderers/index.js.map +1 -0
- package/dist/react/renderers/message.js +41 -0
- package/dist/react/renderers/message.js.map +1 -0
- package/dist/react/renderers/number.js +37 -0
- package/dist/react/renderers/number.js.map +1 -0
- package/dist/react/renderers/region.js +43 -0
- package/dist/react/renderers/region.js.map +1 -0
- package/dist/react/renderers/repeater.js +131 -0
- package/dist/react/renderers/repeater.js.map +1 -0
- package/dist/react/renderers/select.js +35 -0
- package/dist/react/renderers/select.js.map +1 -0
- package/dist/react/renderers/text.js +34 -0
- package/dist/react/renderers/text.js.map +1 -0
- package/dist/react/renderers/textarea.js +33 -0
- package/dist/react/renderers/textarea.js.map +1 -0
- package/dist/react/resolveForm.js +16 -0
- package/dist/react/resolveForm.js.map +1 -0
- package/dist/react/state.d.ts +52 -0
- package/dist/react/state.js +125 -0
- package/dist/react/state.js.map +1 -0
- package/dist/react/submitForm.d.ts +31 -0
- package/dist/react/submitForm.js +58 -0
- package/dist/react/submitForm.js.map +1 -0
- package/dist/react/uploadFile.d.ts +23 -0
- package/dist/react/uploadFile.js +39 -0
- package/dist/react/uploadFile.js.map +1 -0
- package/dist/react/useField.d.ts +13 -0
- package/dist/react/useField.js +49 -0
- package/dist/react/useField.js.map +1 -0
- package/dist/react/useFormState.d.ts +8 -0
- package/dist/react/useFormState.js +9 -0
- package/dist/react/useFormState.js.map +1 -0
- package/dist/react/useFormStep.d.ts +8 -0
- package/dist/react/useFormStep.js +9 -0
- package/dist/react/useFormStep.js.map +1 -0
- package/dist/react/validateField.js +27 -0
- package/dist/react/validateField.js.map +1 -0
- package/dist/recall/interpolate.d.ts +11 -0
- package/dist/recall/interpolate.js +17 -0
- package/dist/recall/interpolate.js.map +1 -0
- package/dist/recall/resolver.d.ts +22 -0
- package/dist/recall/resolver.js +48 -0
- package/dist/recall/resolver.js.map +1 -0
- package/dist/spam/captcha.d.ts +13 -0
- package/dist/spam/captcha.js +12 -0
- package/dist/spam/captcha.js.map +1 -0
- package/dist/spam/clientIp.js +9 -0
- package/dist/spam/clientIp.js.map +1 -0
- package/dist/spam/constants.d.ts +12 -0
- package/dist/spam/constants.js +21 -0
- package/dist/spam/constants.js.map +1 -0
- package/dist/spam/identify.d.ts +12 -0
- package/dist/spam/identify.js +17 -0
- package/dist/spam/identify.js.map +1 -0
- package/dist/spam/providers/hcaptcha.d.ts +17 -0
- package/dist/spam/providers/hcaptcha.js +18 -0
- package/dist/spam/providers/hcaptcha.js.map +1 -0
- package/dist/spam/providers/recaptcha.d.ts +23 -0
- package/dist/spam/providers/recaptcha.js +23 -0
- package/dist/spam/providers/recaptcha.js.map +1 -0
- package/dist/spam/providers/siteverify.js +34 -0
- package/dist/spam/providers/siteverify.js.map +1 -0
- package/dist/spam/providers/turnstile.d.ts +17 -0
- package/dist/spam/providers/turnstile.js +18 -0
- package/dist/spam/providers/turnstile.js.map +1 -0
- package/dist/spam/rateLimiter.d.ts +18 -0
- package/dist/spam/rateLimiter.js +41 -0
- package/dist/spam/rateLimiter.js.map +1 -0
- package/dist/spam/reserved.js +30 -0
- package/dist/spam/reserved.js.map +1 -0
- package/dist/spam/resolveSpam.d.ts +12 -0
- package/dist/spam/resolveSpam.js +43 -0
- package/dist/spam/resolveSpam.js.map +1 -0
- package/dist/spam/spamGuard.js +81 -0
- package/dist/spam/spamGuard.js.map +1 -0
- package/dist/spam/types.d.ts +88 -0
- package/dist/spam/uploadHooks.js +33 -0
- package/dist/spam/uploadHooks.js.map +1 -0
- package/dist/submissions/SubmissionAnswers.d.ts +14 -0
- package/dist/submissions/SubmissionAnswers.js +137 -0
- package/dist/submissions/SubmissionAnswers.js.map +1 -0
- package/dist/submissions/SubmissionAnswersClient.js +178 -0
- package/dist/submissions/SubmissionAnswersClient.js.map +1 -0
- package/dist/submissions/coerceBoolean.js +14 -0
- package/dist/submissions/coerceBoolean.js.map +1 -0
- package/dist/submissions/createSubmission.d.ts +36 -0
- package/dist/submissions/createSubmission.js +26 -0
- package/dist/submissions/createSubmission.js.map +1 -0
- package/dist/submissions/runSubmission.d.ts +10 -0
- package/dist/submissions/runSubmission.js +306 -0
- package/dist/submissions/runSubmission.js.map +1 -0
- package/dist/submissions/types.d.ts +41 -0
- package/dist/submissions/validateSubmission.js +110 -0
- package/dist/submissions/validateSubmission.js.map +1 -0
- package/dist/submissions/votedCookie.d.ts +13 -0
- package/dist/submissions/votedCookie.js +27 -0
- package/dist/submissions/votedCookie.js.map +1 -0
- package/dist/translations/clientRuntimeKeys.d.ts +17 -0
- package/dist/translations/clientRuntimeKeys.js +46 -0
- package/dist/translations/clientRuntimeKeys.js.map +1 -0
- package/dist/translations/de.d.ts +12 -0
- package/dist/translations/de.js +309 -0
- package/dist/translations/de.js.map +1 -0
- package/dist/translations/en.d.ts +12 -0
- package/dist/translations/en.js +309 -0
- package/dist/translations/en.js.map +1 -0
- package/dist/translations/index.d.ts +23 -0
- package/dist/translations/index.js +37 -0
- package/dist/translations/index.js.map +1 -0
- package/dist/translations/keys.d.ts +308 -0
- package/dist/translations/keys.js +308 -0
- package/dist/translations/keys.js.map +1 -0
- package/dist/translations/makeTranslate.d.ts +15 -0
- package/dist/translations/makeTranslate.js +20 -0
- package/dist/translations/makeTranslate.js.map +1 -0
- package/dist/translations/server.js +32 -0
- package/dist/translations/server.js.map +1 -0
- package/dist/translations/useTranslation.js +12 -0
- package/dist/translations/useTranslation.js.map +1 -0
- package/dist/uploads/captureFileRef.d.ts +34 -0
- package/dist/uploads/captureFileRef.js +43 -0
- package/dist/uploads/captureFileRef.js.map +1 -0
- package/dist/uploads/formatBytes.d.ts +9 -0
- package/dist/uploads/formatBytes.js +25 -0
- package/dist/uploads/formatBytes.js.map +1 -0
- package/dist/uploads/resolveFileRef.d.ts +26 -0
- package/dist/uploads/resolveFileRef.js +45 -0
- package/dist/uploads/resolveFileRef.js.map +1 -0
- package/dist/uploads/types.d.ts +19 -0
- package/dist/validation/buildRuleBlocks.js +47 -0
- package/dist/validation/buildRuleBlocks.js.map +1 -0
- package/dist/validation/builtin/email.js +20 -0
- package/dist/validation/builtin/email.js.map +1 -0
- package/dist/validation/builtin/index.d.ts +14 -0
- package/dist/validation/builtin/index.js +38 -0
- package/dist/validation/builtin/index.js.map +1 -0
- package/dist/validation/builtin/matchesField.js +16 -0
- package/dist/validation/builtin/matchesField.js.map +1 -0
- package/dist/validation/builtin/max.js +22 -0
- package/dist/validation/builtin/max.js.map +1 -0
- package/dist/validation/builtin/maxDate.js +24 -0
- package/dist/validation/builtin/maxDate.js.map +1 -0
- package/dist/validation/builtin/maxLength.js +27 -0
- package/dist/validation/builtin/maxLength.js.map +1 -0
- package/dist/validation/builtin/min.js +22 -0
- package/dist/validation/builtin/min.js.map +1 -0
- package/dist/validation/builtin/minDate.js +24 -0
- package/dist/validation/builtin/minDate.js.map +1 -0
- package/dist/validation/builtin/minLength.js +27 -0
- package/dist/validation/builtin/minLength.js.map +1 -0
- package/dist/validation/builtin/notAlreadySubmitted.js +34 -0
- package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -0
- package/dist/validation/builtin/oneOf.js +35 -0
- package/dist/validation/builtin/oneOf.js.map +1 -0
- package/dist/validation/builtin/pattern.js +50 -0
- package/dist/validation/builtin/pattern.js.map +1 -0
- package/dist/validation/builtin/url.js +23 -0
- package/dist/validation/builtin/url.js.map +1 -0
- package/dist/validation/builtin/validateDateBound.js +18 -0
- package/dist/validation/builtin/validateDateBound.js.map +1 -0
- package/dist/validation/builtin/validateRegexParams.js +44 -0
- package/dist/validation/builtin/validateRegexParams.js.map +1 -0
- package/dist/validation/defineValidationRule.d.ts +12 -0
- package/dist/validation/defineValidationRule.js +11 -0
- package/dist/validation/defineValidationRule.js.map +1 -0
- package/dist/validation/emailPattern.js +10 -0
- package/dist/validation/emailPattern.js.map +1 -0
- package/dist/validation/fieldTargetParam.d.ts +22 -0
- package/dist/validation/fieldTargetParam.js +38 -0
- package/dist/validation/fieldTargetParam.js.map +1 -0
- package/dist/validation/message.js +14 -0
- package/dist/validation/message.js.map +1 -0
- package/dist/validation/registry.d.ts +11 -0
- package/dist/validation/registry.js +13 -0
- package/dist/validation/registry.js.map +1 -0
- package/dist/validation/runValidation.js +90 -0
- package/dist/validation/runValidation.js.map +1 -0
- package/dist/validation/types.d.ts +70 -0
- package/dist/validation/validateUrl.js +22 -0
- package/dist/validation/validateUrl.js.map +1 -0
- package/package.json +12 -7
- package/styles/form-builder.css +21 -11
- package/dist/constants-B-BUfetP.d.ts +0 -288
- package/dist/exports/client.js.map +0 -1
- package/dist/exports/react.js.map +0 -1
- package/dist/exports/rsc.js.map +0 -1
- package/dist/fieldTypes-B8jkNRob.d.ts +0 -188
- package/dist/fieldTypes-CzhhJXjg.js.map +0 -1
- package/dist/index-DfFYGbVF.d.ts +0 -481
- package/dist/keys-N5xGiUsh.js +0 -132
- package/dist/keys-N5xGiUsh.js.map +0 -1
- package/dist/registry-CoCyhtvB.js +0 -282
- package/dist/registry-CoCyhtvB.js.map +0 -1
- package/dist/resolver-OeQyVH2N.js +0 -665
- package/dist/resolver-OeQyVH2N.js.map +0 -1
- package/dist/translations-edMqq_2e.js +0 -152
- package/dist/translations-edMqq_2e.js.map +0 -1
- package/dist/types-DsJ_6kGJ.d.ts +0 -23
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { keys } from "../translations/keys.js";
|
|
3
|
+
import { en } from "../translations/en.js";
|
|
4
|
+
import { makeTranslate } from "../translations/makeTranslate.js";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/react/FormResults.tsx
|
|
7
|
+
const OneResult = ({ result, t, showCounts, winningValues }) => {
|
|
8
|
+
if (result.total === 0) return /* @__PURE__ */ jsxs("section", {
|
|
9
|
+
className: "fb-results__field",
|
|
10
|
+
children: [result.label ? /* @__PURE__ */ jsx("h3", {
|
|
11
|
+
className: "fb-results__label",
|
|
12
|
+
children: result.label
|
|
13
|
+
}) : null, /* @__PURE__ */ jsx("p", {
|
|
14
|
+
className: "fb-results__empty",
|
|
15
|
+
children: t(keys.resultsNoResponses)
|
|
16
|
+
})]
|
|
17
|
+
});
|
|
18
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
19
|
+
className: "fb-results__field",
|
|
20
|
+
children: [
|
|
21
|
+
result.label ? /* @__PURE__ */ jsx("h3", {
|
|
22
|
+
className: "fb-results__label",
|
|
23
|
+
children: result.label
|
|
24
|
+
}) : null,
|
|
25
|
+
/* @__PURE__ */ jsx("ul", {
|
|
26
|
+
className: "fb-results__list",
|
|
27
|
+
children: result.buckets.map((bucket) => {
|
|
28
|
+
const isWinner = winningValues?.includes(bucket.value) ?? false;
|
|
29
|
+
return /* @__PURE__ */ jsxs("li", {
|
|
30
|
+
className: isWinner ? "fb-results__row fb-results__bucket--winner" : "fb-results__row",
|
|
31
|
+
children: [
|
|
32
|
+
/* @__PURE__ */ jsxs("span", {
|
|
33
|
+
className: "fb-results__option",
|
|
34
|
+
children: [bucket.label, isWinner ? /* @__PURE__ */ jsx("span", {
|
|
35
|
+
className: "fb-results__winner-badge",
|
|
36
|
+
children: t(keys.resultsWinner)
|
|
37
|
+
}) : null]
|
|
38
|
+
}),
|
|
39
|
+
/* @__PURE__ */ jsx("span", {
|
|
40
|
+
className: "fb-results__bar",
|
|
41
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
42
|
+
className: "fb-results__bar-fill",
|
|
43
|
+
style: { width: `${bucket.percentage}%` },
|
|
44
|
+
"aria-hidden": "true"
|
|
45
|
+
})
|
|
46
|
+
}),
|
|
47
|
+
/* @__PURE__ */ jsxs("span", {
|
|
48
|
+
className: "fb-results__pct",
|
|
49
|
+
children: [bucket.percentage, "%"]
|
|
50
|
+
}),
|
|
51
|
+
showCounts ? /* @__PURE__ */ jsx("span", {
|
|
52
|
+
className: "fb-results__count",
|
|
53
|
+
children: bucket.count
|
|
54
|
+
}) : null
|
|
55
|
+
]
|
|
56
|
+
}, bucket.value);
|
|
57
|
+
})
|
|
58
|
+
}),
|
|
59
|
+
/* @__PURE__ */ jsxs("p", {
|
|
60
|
+
className: "fb-results__total",
|
|
61
|
+
children: [
|
|
62
|
+
result.total,
|
|
63
|
+
" ",
|
|
64
|
+
t(keys.resultsResponses),
|
|
65
|
+
result.truncated ? ` (${t(keys.resultsTruncated)})` : ""
|
|
66
|
+
]
|
|
67
|
+
})
|
|
68
|
+
]
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Presentational results view for polls and survey summaries: per-option bars with percentages. Headless,
|
|
73
|
+
* data resolved server-side via `aggregateFieldResponses`/`aggregateFormResponses` and passed in (it never
|
|
74
|
+
* fetches). The option label, count, and percentage are real text (the accessible content); the bar fill
|
|
75
|
+
* is `aria-hidden` visual sugar sized by inline width. With `winningValues`, every matching bucket gets
|
|
76
|
+
* the winner class and a translated badge (real text, so the outcome is accessible); a tie highlights more than one.
|
|
77
|
+
*/
|
|
78
|
+
const FormResults = ({ results, t, showCounts = true, winningValues }) => {
|
|
79
|
+
const translate = t ?? makeTranslate(en);
|
|
80
|
+
return /* @__PURE__ */ jsx("div", {
|
|
81
|
+
className: "fb-results",
|
|
82
|
+
children: (Array.isArray(results) ? results : [results]).map((result) => /* @__PURE__ */ jsx(OneResult, {
|
|
83
|
+
result,
|
|
84
|
+
t: translate,
|
|
85
|
+
showCounts,
|
|
86
|
+
winningValues
|
|
87
|
+
}, result.field))
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
//#endregion
|
|
91
|
+
export { FormResults };
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=FormResults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormResults.js","names":[],"sources":["../../src/react/FormResults.tsx"],"sourcesContent":["'use client'\n\nimport type { ReactNode } from 'react'\nimport type { FieldAggregation } from '../aggregation/types'\nimport { en } from '../translations/en'\nimport { keys } from '../translations/keys'\nimport { makeTranslate } from '../translations/makeTranslate'\nimport type { RendererTranslate } from './contract'\n\nexport type FormResultsProps = {\n\t/** One field aggregation or several (a survey summary), resolved server-side and passed in. */\n\tresults: FieldAggregation | FieldAggregation[]\n\t/** Localized translator for built-in copy. Defaults to identity (returns the key). */\n\tt?: RendererTranslate\n\tlocale?: string\n\t/** Show the raw count beside each option. Default true. */\n\tshowCounts?: boolean\n\t/** The recorded outcome's stable option values; every matching bucket is highlighted as a winner (a tie highlights more than one). */\n\twinningValues?: string[]\n}\n\nconst OneResult = ({\n\tresult,\n\tt,\n\tshowCounts,\n\twinningValues,\n}: {\n\tresult: FieldAggregation\n\tt: RendererTranslate\n\tshowCounts: boolean\n\twinningValues?: string[]\n}): ReactNode => {\n\tif (result.total === 0) {\n\t\treturn (\n\t\t\t<section className=\"fb-results__field\">\n\t\t\t\t{result.label ? <h3 className=\"fb-results__label\">{result.label}</h3> : null}\n\t\t\t\t<p className=\"fb-results__empty\">{t(keys.resultsNoResponses)}</p>\n\t\t\t</section>\n\t\t)\n\t}\n\treturn (\n\t\t<section className=\"fb-results__field\">\n\t\t\t{result.label ? <h3 className=\"fb-results__label\">{result.label}</h3> : null}\n\t\t\t<ul className=\"fb-results__list\">\n\t\t\t\t{result.buckets.map((bucket) => {\n\t\t\t\t\tconst isWinner = winningValues?.includes(bucket.value) ?? false\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tkey={bucket.value}\n\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\tisWinner ? 'fb-results__row fb-results__bucket--winner' : 'fb-results__row'\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span className=\"fb-results__option\">\n\t\t\t\t\t\t\t\t{bucket.label}\n\t\t\t\t\t\t\t\t{isWinner ? (\n\t\t\t\t\t\t\t\t\t<span className=\"fb-results__winner-badge\">{t(keys.resultsWinner)}</span>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span className=\"fb-results__bar\">\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclassName=\"fb-results__bar-fill\"\n\t\t\t\t\t\t\t\t\tstyle={{ width: `${bucket.percentage}%` }}\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<span className=\"fb-results__pct\">{bucket.percentage}%</span>\n\t\t\t\t\t\t\t{showCounts ? <span className=\"fb-results__count\">{bucket.count}</span> : null}\n\t\t\t\t\t\t</li>\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t</ul>\n\t\t\t<p className=\"fb-results__total\">\n\t\t\t\t{result.total} {t(keys.resultsResponses)}\n\t\t\t\t{result.truncated ? ` (${t(keys.resultsTruncated)})` : ''}\n\t\t\t</p>\n\t\t</section>\n\t)\n}\n\n/**\n * Presentational results view for polls and survey summaries: per-option bars with percentages. Headless,\n * data resolved server-side via `aggregateFieldResponses`/`aggregateFormResponses` and passed in (it never\n * fetches). The option label, count, and percentage are real text (the accessible content); the bar fill\n * is `aria-hidden` visual sugar sized by inline width. With `winningValues`, every matching bucket gets\n * the winner class and a translated badge (real text, so the outcome is accessible); a tie highlights more than one.\n */\nexport const FormResults = ({\n\tresults,\n\tt,\n\tshowCounts = true,\n\twinningValues,\n}: FormResultsProps): ReactNode => {\n\tconst translate: RendererTranslate = t ?? makeTranslate(en)\n\tconst list = Array.isArray(results) ? results : [results]\n\treturn (\n\t\t<div className=\"fb-results\">\n\t\t\t{list.map((result) => (\n\t\t\t\t<OneResult\n\t\t\t\t\tkey={result.field}\n\t\t\t\t\tresult={result}\n\t\t\t\t\tt={translate}\n\t\t\t\t\tshowCounts={showCounts}\n\t\t\t\t\twinningValues={winningValues}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</div>\n\t)\n}\n"],"mappings":";;;;;;AAqBA,MAAM,aAAa,EAClB,QACA,GACA,YACA,oBAMgB;CAChB,IAAI,OAAO,UAAU,GACpB,OACC,qBAAC,WAAD;EAAS,WAAU;YAAnB,CACE,OAAO,QAAQ,oBAAC,MAAD;GAAI,WAAU;aAAqB,OAAO;EAAU,CAAA,IAAI,MACxE,oBAAC,KAAD;GAAG,WAAU;aAAqB,EAAE,KAAK,kBAAkB;EAAK,CAAA,CACxD;;CAGX,OACC,qBAAC,WAAD;EAAS,WAAU;YAAnB;GACE,OAAO,QAAQ,oBAAC,MAAD;IAAI,WAAU;cAAqB,OAAO;GAAU,CAAA,IAAI;GACxE,oBAAC,MAAD;IAAI,WAAU;cACZ,OAAO,QAAQ,KAAK,WAAW;KAC/B,MAAM,WAAW,eAAe,SAAS,OAAO,KAAK,KAAK;KAC1D,OACC,qBAAC,MAAD;MAEC,WACC,WAAW,+CAA+C;gBAH5D;OAMC,qBAAC,QAAD;QAAM,WAAU;kBAAhB,CACE,OAAO,OACP,WACA,oBAAC,QAAD;SAAM,WAAU;mBAA4B,EAAE,KAAK,aAAa;QAAQ,CAAA,IACrE,IACC;;OACN,oBAAC,QAAD;QAAM,WAAU;kBACf,oBAAC,QAAD;SACC,WAAU;SACV,OAAO,EAAE,OAAO,GAAG,OAAO,WAAW,GAAG;SACxC,eAAY;QACZ,CAAA;OACI,CAAA;OACN,qBAAC,QAAD;QAAM,WAAU;kBAAhB,CAAmC,OAAO,YAAW,GAAO;;OAC3D,aAAa,oBAAC,QAAD;QAAM,WAAU;kBAAqB,OAAO;OAAY,CAAA,IAAI;MACvE;QApBE,OAAO,KAoBT;IAEN,CAAC;GACE,CAAA;GACJ,qBAAC,KAAD;IAAG,WAAU;cAAb;KACE,OAAO;KAAM;KAAE,EAAE,KAAK,gBAAgB;KACtC,OAAO,YAAY,KAAK,EAAE,KAAK,gBAAgB,EAAE,KAAK;IACrD;;EACK;;AAEX;;;;;;;;AASA,MAAa,eAAe,EAC3B,SACA,GACA,aAAa,MACb,oBACkC;CAClC,MAAM,YAA+B,KAAK,cAAc,EAAE;CAE1D,OACC,oBAAC,OAAD;EAAK,WAAU;aAFH,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO,GAGhD,KAAK,WACV,oBAAC,WAAD;GAES;GACR,GAAG;GACS;GACG;EACf,GALK,OAAO,KAKZ,CACD;CACG,CAAA;AAEP"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/react/FormSteps.d.ts
|
|
2
|
+
type FormStepsProps = {
|
|
3
|
+
/** Additional CSS class on the wrapping `.fb-form-steps` list. */className?: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Step-progress indicator for multi-step forms: an ordered list of the flow's steps with the
|
|
7
|
+
* current one marked via `aria-current="step"` and a `--current` class. Step labels use the
|
|
8
|
+
* step's title, falling back to the translated "Step {n}" (same semantics as the admin flow
|
|
9
|
+
* builder). Carries no styling opinions beyond `fb-form-steps` classes. Renders nothing when
|
|
10
|
+
* the form has fewer than two steps. Must render inside `<Form>`.
|
|
11
|
+
*/
|
|
12
|
+
declare const FormSteps: ({
|
|
13
|
+
className
|
|
14
|
+
}: FormStepsProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { FormSteps, FormStepsProps };
|
|
17
|
+
//# sourceMappingURL=FormSteps.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { keys } from "../translations/keys.js";
|
|
3
|
+
import { stepLabel } from "../flow/stepLabel.js";
|
|
4
|
+
import { cn } from "./cn.js";
|
|
5
|
+
import { useFormContext } from "./FormContext.js";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
//#region src/react/FormSteps.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Step-progress indicator for multi-step forms: an ordered list of the flow's steps with the
|
|
10
|
+
* current one marked via `aria-current="step"` and a `--current` class. Step labels use the
|
|
11
|
+
* step's title, falling back to the translated "Step {n}" (same semantics as the admin flow
|
|
12
|
+
* builder). Carries no styling opinions beyond `fb-form-steps` classes. Renders nothing when
|
|
13
|
+
* the form has fewer than two steps. Must render inside `<Form>`.
|
|
14
|
+
*/
|
|
15
|
+
const FormSteps = ({ className }) => {
|
|
16
|
+
const { step, t } = useFormContext();
|
|
17
|
+
const steps = step.flow?.steps;
|
|
18
|
+
if (!steps || steps.length < 2) return null;
|
|
19
|
+
const fallbackTitle = t(keys.flowStepFallbackTitle);
|
|
20
|
+
return /* @__PURE__ */ jsx("ol", {
|
|
21
|
+
className: cn("fb-form-steps", className),
|
|
22
|
+
children: steps.map((flowStep, index) => {
|
|
23
|
+
const current = index === step.stepIndex;
|
|
24
|
+
return /* @__PURE__ */ jsx("li", {
|
|
25
|
+
className: cn("fb-form-steps__step", current && "fb-form-steps__step--current"),
|
|
26
|
+
"aria-current": current ? "step" : void 0,
|
|
27
|
+
children: stepLabel(flowStep, index, fallbackTitle)
|
|
28
|
+
}, flowStep.id);
|
|
29
|
+
})
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
//#endregion
|
|
33
|
+
export { FormSteps };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=FormSteps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormSteps.js","names":[],"sources":["../../src/react/FormSteps.tsx"],"sourcesContent":["'use client'\n\nimport { stepLabel } from '../flow/stepLabel'\nimport { keys } from '../translations/keys'\nimport { cn } from './cn'\nimport { useFormContext } from './FormContext'\n\nexport type FormStepsProps = {\n\t/** Additional CSS class on the wrapping `.fb-form-steps` list. */\n\tclassName?: string\n}\n\n/**\n * Step-progress indicator for multi-step forms: an ordered list of the flow's steps with the\n * current one marked via `aria-current=\"step\"` and a `--current` class. Step labels use the\n * step's title, falling back to the translated \"Step {n}\" (same semantics as the admin flow\n * builder). Carries no styling opinions beyond `fb-form-steps` classes. Renders nothing when\n * the form has fewer than two steps. Must render inside `<Form>`.\n */\nexport const FormSteps = ({ className }: FormStepsProps) => {\n\tconst { step, t } = useFormContext()\n\tconst steps = step.flow?.steps\n\tif (!steps || steps.length < 2) {\n\t\treturn null\n\t}\n\tconst fallbackTitle = t(keys.flowStepFallbackTitle)\n\treturn (\n\t\t<ol className={cn('fb-form-steps', className)}>\n\t\t\t{steps.map((flowStep, index) => {\n\t\t\t\tconst current = index === step.stepIndex\n\t\t\t\treturn (\n\t\t\t\t\t<li\n\t\t\t\t\t\tkey={flowStep.id}\n\t\t\t\t\t\tclassName={cn('fb-form-steps__step', current && 'fb-form-steps__step--current')}\n\t\t\t\t\t\taria-current={current ? 'step' : undefined}\n\t\t\t\t\t>\n\t\t\t\t\t\t{stepLabel(flowStep, index, fallbackTitle)}\n\t\t\t\t\t</li>\n\t\t\t\t)\n\t\t\t})}\n\t\t</ol>\n\t)\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,MAAa,aAAa,EAAE,gBAAgC;CAC3D,MAAM,EAAE,MAAM,MAAM,eAAe;CACnC,MAAM,QAAQ,KAAK,MAAM;CACzB,IAAI,CAAC,SAAS,MAAM,SAAS,GAC5B,OAAO;CAER,MAAM,gBAAgB,EAAE,KAAK,qBAAqB;CAClD,OACC,oBAAC,MAAD;EAAI,WAAW,GAAG,iBAAiB,SAAS;YAC1C,MAAM,KAAK,UAAU,UAAU;GAC/B,MAAM,UAAU,UAAU,KAAK;GAC/B,OACC,oBAAC,MAAD;IAEC,WAAW,GAAG,uBAAuB,WAAW,8BAA8B;IAC9E,gBAAc,UAAU,SAAS,KAAA;cAEhC,UAAU,UAAU,OAAO,aAAa;GACtC,GALE,SAAS,EAKX;EAEN,CAAC;CACE,CAAA;AAEN"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Ref } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/react/Honeypot.d.ts
|
|
4
|
+
type HoneypotProps = {
|
|
5
|
+
name: string;
|
|
6
|
+
inputRef?: Ref<HTMLInputElement>;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* A visually hidden honeypot decoy. Real users never see or tab to it; bots that fill every input
|
|
10
|
+
* trip it, and the server rejects the submission.
|
|
11
|
+
*
|
|
12
|
+
* `autoComplete="new-password"` is used instead of `"off"` because Chrome frequently ignores `"off"`
|
|
13
|
+
* but reliably respects `"new-password"` to prevent autofill. The field name is intentionally generic
|
|
14
|
+
* (no "email" token) to avoid Chrome's email-address heuristic.
|
|
15
|
+
*/
|
|
16
|
+
declare const Honeypot: ({
|
|
17
|
+
name,
|
|
18
|
+
inputRef
|
|
19
|
+
}: HoneypotProps) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { Honeypot, HoneypotProps };
|
|
22
|
+
//# sourceMappingURL=Honeypot.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
//#region src/react/Honeypot.tsx
|
|
4
|
+
const HIDDEN = {
|
|
5
|
+
position: "absolute",
|
|
6
|
+
width: 1,
|
|
7
|
+
height: 1,
|
|
8
|
+
padding: 0,
|
|
9
|
+
margin: -1,
|
|
10
|
+
overflow: "hidden",
|
|
11
|
+
clip: "rect(0, 0, 0, 0)",
|
|
12
|
+
whiteSpace: "nowrap",
|
|
13
|
+
border: 0
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* A visually hidden honeypot decoy. Real users never see or tab to it; bots that fill every input
|
|
17
|
+
* trip it, and the server rejects the submission.
|
|
18
|
+
*
|
|
19
|
+
* `autoComplete="new-password"` is used instead of `"off"` because Chrome frequently ignores `"off"`
|
|
20
|
+
* but reliably respects `"new-password"` to prevent autofill. The field name is intentionally generic
|
|
21
|
+
* (no "email" token) to avoid Chrome's email-address heuristic.
|
|
22
|
+
*/
|
|
23
|
+
const Honeypot = ({ name, inputRef }) => /* @__PURE__ */ jsx("div", {
|
|
24
|
+
"aria-hidden": "true",
|
|
25
|
+
style: HIDDEN,
|
|
26
|
+
children: /* @__PURE__ */ jsxs("label", { children: ["Leave this field empty", /* @__PURE__ */ jsx("input", {
|
|
27
|
+
ref: inputRef,
|
|
28
|
+
type: "text",
|
|
29
|
+
name,
|
|
30
|
+
tabIndex: -1,
|
|
31
|
+
autoComplete: "new-password",
|
|
32
|
+
defaultValue: ""
|
|
33
|
+
})] })
|
|
34
|
+
});
|
|
35
|
+
//#endregion
|
|
36
|
+
export { Honeypot };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=Honeypot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Honeypot.js","names":[],"sources":["../../src/react/Honeypot.tsx"],"sourcesContent":["'use client'\n\nimport type { CSSProperties, Ref } from 'react'\n\nconst HIDDEN: CSSProperties = {\n\tposition: 'absolute',\n\twidth: 1,\n\theight: 1,\n\tpadding: 0,\n\tmargin: -1,\n\toverflow: 'hidden',\n\tclip: 'rect(0, 0, 0, 0)',\n\twhiteSpace: 'nowrap',\n\tborder: 0,\n}\n\nexport type HoneypotProps = {\n\tname: string\n\tinputRef?: Ref<HTMLInputElement>\n}\n\n/**\n * A visually hidden honeypot decoy. Real users never see or tab to it; bots that fill every input\n * trip it, and the server rejects the submission.\n *\n * `autoComplete=\"new-password\"` is used instead of `\"off\"` because Chrome frequently ignores `\"off\"`\n * but reliably respects `\"new-password\"` to prevent autofill. The field name is intentionally generic\n * (no \"email\" token) to avoid Chrome's email-address heuristic.\n */\nexport const Honeypot = ({ name, inputRef }: HoneypotProps) => (\n\t<div aria-hidden=\"true\" style={HIDDEN}>\n\t\t<label>\n\t\t\tLeave this field empty\n\t\t\t<input\n\t\t\t\tref={inputRef}\n\t\t\t\ttype=\"text\"\n\t\t\t\tname={name}\n\t\t\t\ttabIndex={-1}\n\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\tdefaultValue=\"\"\n\t\t\t/>\n\t\t</label>\n\t</div>\n)\n"],"mappings":";;;AAIA,MAAM,SAAwB;CAC7B,UAAU;CACV,OAAO;CACP,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,UAAU;CACV,MAAM;CACN,YAAY;CACZ,QAAQ;AACT;;;;;;;;;AAeA,MAAa,YAAY,EAAE,MAAM,eAChC,oBAAC,OAAD;CAAK,eAAY;CAAO,OAAO;WAC9B,qBAAC,SAAD,EAAA,UAAA,CAAO,0BAEN,oBAAC,SAAD;EACC,KAAK;EACL,MAAK;EACC;EACN,UAAU;EACV,cAAa;EACb,cAAa;CACb,CAAA,CACK,EAAA,CAAA;AACH,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { FormProps } from "./Form.js";
|
|
2
|
+
import { fetchFormResults } from "./fetchResults.js";
|
|
3
|
+
|
|
4
|
+
//#region src/react/Poll.d.ts
|
|
5
|
+
type PollProps = FormProps & {
|
|
6
|
+
/** The choice field whose results are shown after voting (should match the form's public `poll.resultsField`). */resultsField: string; /** localStorage key for the per-browser voted guard. Default `fb-poll-{form.id}`. */
|
|
7
|
+
storageKey?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Server-known voted state, ORed with the localStorage guard: `true` marks the visitor as voted;
|
|
10
|
+
* `false`/omitted falls back to localStorage. SSR hosts using the plugin's `poll.votedCookie`
|
|
11
|
+
* option pass `hasVotedCookie(cookieHeader, form.id)` here.
|
|
12
|
+
*/
|
|
13
|
+
hasVoted?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Injectable results fetch (testing); defaults to `fetchFormResults`. Pass a stable reference (module
|
|
16
|
+
* scope, `useCallback`, or `useMemo`): an inline function re-runs the load effect and double-fetches.
|
|
17
|
+
*/
|
|
18
|
+
fetchResultsImpl?: typeof fetchFormResults;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* A poll: renders `<Form>` while open and not yet voted, then fetches the aggregate results and shows
|
|
22
|
+
* `<FormResults>`. Lifecycle comes from `form.poll`: past `closesAt` the poll is closed (a translated
|
|
23
|
+
* notice plus results, which the endpoint serves for any visibility once closed); a voted-but-open
|
|
24
|
+
* `afterClose` poll shows a translated wait notice instead of fetching (the endpoint would refuse). A
|
|
25
|
+
* recorded `outcome.winningValues` (via `resolvePollOutcome`) supersedes everything: a translated final
|
|
26
|
+
* notice plus results with every winning bucket highlighted (a tie highlights more than one). A
|
|
27
|
+
* per-browser localStorage flag (`storageKey`) skips straight to results on revisit; `hasVoted: true`
|
|
28
|
+
* (e.g. from the server-set voted cookie) marks voted regardless of localStorage. The guard is UX, not
|
|
29
|
+
* integrity (bypassable): server-enforced
|
|
30
|
+
* one-per-identity dedup composes via `req.user` (authed forms) or a `notAlreadySubmitted` rule.
|
|
31
|
+
*/
|
|
32
|
+
declare const Poll: ({
|
|
33
|
+
resultsField,
|
|
34
|
+
storageKey,
|
|
35
|
+
hasVoted,
|
|
36
|
+
fetchResultsImpl,
|
|
37
|
+
apiRoute,
|
|
38
|
+
onSuccess,
|
|
39
|
+
...formProps
|
|
40
|
+
}: PollProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { Poll, PollProps };
|
|
43
|
+
//# sourceMappingURL=Poll.d.ts.map
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { keys } from "../translations/keys.js";
|
|
3
|
+
import { isPollClosed } from "../form/pollState.js";
|
|
4
|
+
import { en } from "../translations/en.js";
|
|
5
|
+
import { makeTranslate } from "../translations/makeTranslate.js";
|
|
6
|
+
import { Form } from "./Form.js";
|
|
7
|
+
import { FormResults } from "./FormResults.js";
|
|
8
|
+
import { fetchFormResults } from "./fetchResults.js";
|
|
9
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
11
|
+
//#region src/react/Poll.tsx
|
|
12
|
+
const readVoted = (key) => {
|
|
13
|
+
try {
|
|
14
|
+
return window.localStorage.getItem(key) != null;
|
|
15
|
+
} catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const writeVoted = (key) => {
|
|
20
|
+
try {
|
|
21
|
+
window.localStorage.setItem(key, "1");
|
|
22
|
+
} catch {}
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* A poll: renders `<Form>` while open and not yet voted, then fetches the aggregate results and shows
|
|
26
|
+
* `<FormResults>`. Lifecycle comes from `form.poll`: past `closesAt` the poll is closed (a translated
|
|
27
|
+
* notice plus results, which the endpoint serves for any visibility once closed); a voted-but-open
|
|
28
|
+
* `afterClose` poll shows a translated wait notice instead of fetching (the endpoint would refuse). A
|
|
29
|
+
* recorded `outcome.winningValues` (via `resolvePollOutcome`) supersedes everything: a translated final
|
|
30
|
+
* notice plus results with every winning bucket highlighted (a tie highlights more than one). A
|
|
31
|
+
* per-browser localStorage flag (`storageKey`) skips straight to results on revisit; `hasVoted: true`
|
|
32
|
+
* (e.g. from the server-set voted cookie) marks voted regardless of localStorage. The guard is UX, not
|
|
33
|
+
* integrity (bypassable): server-enforced
|
|
34
|
+
* one-per-identity dedup composes via `req.user` (authed forms) or a `notAlreadySubmitted` rule.
|
|
35
|
+
*/
|
|
36
|
+
const Poll = ({ resultsField, storageKey, hasVoted, fetchResultsImpl = fetchFormResults, apiRoute, onSuccess, ...formProps }) => {
|
|
37
|
+
const key = storageKey ?? `fb-poll-${formProps.form.id}`;
|
|
38
|
+
const poll = formProps.form.poll;
|
|
39
|
+
const closed = isPollClosed(poll);
|
|
40
|
+
const winningValues = poll?.outcome?.winningValues;
|
|
41
|
+
const finalized = Array.isArray(winningValues) && winningValues.length > 0;
|
|
42
|
+
const resultsAwaitClose = !closed && !finalized && poll?.resultsVisibility === "afterClose";
|
|
43
|
+
const [voted, setVoted] = useState(false);
|
|
44
|
+
const [results, setResults] = useState(null);
|
|
45
|
+
const [loadFailed, setLoadFailed] = useState(false);
|
|
46
|
+
const translate = useMemo(() => formProps.t ?? makeTranslate(en), [formProps.t]);
|
|
47
|
+
const loadResults = useCallback(async () => {
|
|
48
|
+
const result = await fetchResultsImpl({
|
|
49
|
+
formId: formProps.form.id,
|
|
50
|
+
field: resultsField,
|
|
51
|
+
apiRoute
|
|
52
|
+
});
|
|
53
|
+
if (result.ok) {
|
|
54
|
+
setResults(result.results);
|
|
55
|
+
setLoadFailed(false);
|
|
56
|
+
} else setLoadFailed(true);
|
|
57
|
+
}, [
|
|
58
|
+
fetchResultsImpl,
|
|
59
|
+
formProps.form.id,
|
|
60
|
+
resultsField,
|
|
61
|
+
apiRoute
|
|
62
|
+
]);
|
|
63
|
+
const resultsError = /* @__PURE__ */ jsx("p", {
|
|
64
|
+
className: "fb-poll__error",
|
|
65
|
+
role: "alert",
|
|
66
|
+
children: translate(keys.pollResultsError)
|
|
67
|
+
});
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
const already = hasVoted === true || readVoted(key);
|
|
70
|
+
if (already) setVoted(true);
|
|
71
|
+
if (already && !resultsAwaitClose || closed || finalized) loadResults();
|
|
72
|
+
}, [
|
|
73
|
+
hasVoted,
|
|
74
|
+
key,
|
|
75
|
+
loadResults,
|
|
76
|
+
closed,
|
|
77
|
+
resultsAwaitClose,
|
|
78
|
+
finalized
|
|
79
|
+
]);
|
|
80
|
+
const handleSuccess = useCallback((submissionId, result) => {
|
|
81
|
+
writeVoted(key);
|
|
82
|
+
setVoted(true);
|
|
83
|
+
if (!resultsAwaitClose) loadResults();
|
|
84
|
+
onSuccess?.(submissionId, result);
|
|
85
|
+
}, [
|
|
86
|
+
key,
|
|
87
|
+
loadResults,
|
|
88
|
+
onSuccess,
|
|
89
|
+
resultsAwaitClose
|
|
90
|
+
]);
|
|
91
|
+
if (finalized) return /* @__PURE__ */ jsxs("div", {
|
|
92
|
+
className: "fb-poll fb-poll--final",
|
|
93
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
94
|
+
className: "fb-poll__final",
|
|
95
|
+
children: translate(keys.pollFinalResult)
|
|
96
|
+
}), loadFailed ? resultsError : results ? /* @__PURE__ */ jsx(FormResults, {
|
|
97
|
+
results,
|
|
98
|
+
winningValues,
|
|
99
|
+
t: formProps.t,
|
|
100
|
+
locale: formProps.locale
|
|
101
|
+
}) : null]
|
|
102
|
+
});
|
|
103
|
+
if (closed) return /* @__PURE__ */ jsxs("div", {
|
|
104
|
+
className: "fb-poll fb-poll--closed",
|
|
105
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
106
|
+
className: "fb-poll__closed",
|
|
107
|
+
children: translate(keys.pollClosed)
|
|
108
|
+
}), loadFailed ? resultsError : results ? /* @__PURE__ */ jsx(FormResults, {
|
|
109
|
+
results,
|
|
110
|
+
t: formProps.t,
|
|
111
|
+
locale: formProps.locale
|
|
112
|
+
}) : null]
|
|
113
|
+
});
|
|
114
|
+
if (voted) {
|
|
115
|
+
if (resultsAwaitClose) return /* @__PURE__ */ jsx("p", {
|
|
116
|
+
className: "fb-poll__await-close",
|
|
117
|
+
children: translate(keys.pollResultsAfterClose)
|
|
118
|
+
});
|
|
119
|
+
if (loadFailed) return resultsError;
|
|
120
|
+
return results ? /* @__PURE__ */ jsx(FormResults, {
|
|
121
|
+
results,
|
|
122
|
+
t: formProps.t,
|
|
123
|
+
locale: formProps.locale
|
|
124
|
+
}) : null;
|
|
125
|
+
}
|
|
126
|
+
return /* @__PURE__ */ jsx(Form, {
|
|
127
|
+
...formProps,
|
|
128
|
+
apiRoute,
|
|
129
|
+
onSuccess: handleSuccess
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
//#endregion
|
|
133
|
+
export { Poll };
|
|
134
|
+
|
|
135
|
+
//# sourceMappingURL=Poll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Poll.js","names":[],"sources":["../../src/react/Poll.tsx"],"sourcesContent":["'use client'\n\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport type { FieldAggregation } from '../aggregation/types'\nimport { isPollClosed } from '../form/pollState'\nimport { en } from '../translations/en'\nimport { keys } from '../translations/keys'\nimport { makeTranslate } from '../translations/makeTranslate'\nimport { Form, type FormProps } from './Form'\nimport { FormResults } from './FormResults'\nimport { type FetchResultsResult, fetchFormResults } from './fetchResults'\n\nexport type PollProps = FormProps & {\n\t/** The choice field whose results are shown after voting (should match the form's public `poll.resultsField`). */\n\tresultsField: string\n\t/** localStorage key for the per-browser voted guard. Default `fb-poll-{form.id}`. */\n\tstorageKey?: string\n\t/**\n\t * Server-known voted state, ORed with the localStorage guard: `true` marks the visitor as voted;\n\t * `false`/omitted falls back to localStorage. SSR hosts using the plugin's `poll.votedCookie`\n\t * option pass `hasVotedCookie(cookieHeader, form.id)` here.\n\t */\n\thasVoted?: boolean\n\t/**\n\t * Injectable results fetch (testing); defaults to `fetchFormResults`. Pass a stable reference (module\n\t * scope, `useCallback`, or `useMemo`): an inline function re-runs the load effect and double-fetches.\n\t */\n\tfetchResultsImpl?: typeof fetchFormResults\n}\n\nconst readVoted = (key: string): boolean => {\n\ttry {\n\t\treturn window.localStorage.getItem(key) != null\n\t} catch {\n\t\treturn false\n\t}\n}\n\nconst writeVoted = (key: string): void => {\n\ttry {\n\t\twindow.localStorage.setItem(key, '1')\n\t} catch {\n\t\t// Private mode / storage disabled: the guard is best-effort UX, never integrity.\n\t}\n}\n\n/**\n * A poll: renders `<Form>` while open and not yet voted, then fetches the aggregate results and shows\n * `<FormResults>`. Lifecycle comes from `form.poll`: past `closesAt` the poll is closed (a translated\n * notice plus results, which the endpoint serves for any visibility once closed); a voted-but-open\n * `afterClose` poll shows a translated wait notice instead of fetching (the endpoint would refuse). A\n * recorded `outcome.winningValues` (via `resolvePollOutcome`) supersedes everything: a translated final\n * notice plus results with every winning bucket highlighted (a tie highlights more than one). A\n * per-browser localStorage flag (`storageKey`) skips straight to results on revisit; `hasVoted: true`\n * (e.g. from the server-set voted cookie) marks voted regardless of localStorage. The guard is UX, not\n * integrity (bypassable): server-enforced\n * one-per-identity dedup composes via `req.user` (authed forms) or a `notAlreadySubmitted` rule.\n */\nexport const Poll = ({\n\tresultsField,\n\tstorageKey,\n\thasVoted,\n\tfetchResultsImpl = fetchFormResults,\n\tapiRoute,\n\tonSuccess,\n\t...formProps\n}: PollProps) => {\n\tconst key = storageKey ?? `fb-poll-${formProps.form.id}`\n\tconst poll = formProps.form.poll\n\tconst closed = isPollClosed(poll)\n\tconst winningValues = poll?.outcome?.winningValues\n\tconst finalized = Array.isArray(winningValues) && winningValues.length > 0\n\tconst resultsAwaitClose = !closed && !finalized && poll?.resultsVisibility === 'afterClose'\n\tconst [voted, setVoted] = useState(false)\n\tconst [results, setResults] = useState<FieldAggregation[] | null>(null)\n\tconst [loadFailed, setLoadFailed] = useState(false)\n\tconst translate = useMemo(() => formProps.t ?? makeTranslate(en), [formProps.t])\n\n\tconst loadResults = useCallback(async () => {\n\t\tconst result: FetchResultsResult = await fetchResultsImpl({\n\t\t\tformId: formProps.form.id,\n\t\t\tfield: resultsField,\n\t\t\tapiRoute,\n\t\t})\n\t\t// A failed load surfaces as an error, not an empty result set: `[]` would read as \"no votes yet\".\n\t\tif (result.ok) {\n\t\t\tsetResults(result.results)\n\t\t\tsetLoadFailed(false)\n\t\t} else {\n\t\t\tsetLoadFailed(true)\n\t\t}\n\t}, [fetchResultsImpl, formProps.form.id, resultsField, apiRoute])\n\n\tconst resultsError = (\n\t\t<p className=\"fb-poll__error\" role=\"alert\">\n\t\t\t{translate(keys.pollResultsError)}\n\t\t</p>\n\t)\n\n\tuseEffect(() => {\n\t\tconst already = hasVoted === true || readVoted(key)\n\t\tif (already) {\n\t\t\tsetVoted(true)\n\t\t}\n\t\tif ((already && !resultsAwaitClose) || closed || finalized) {\n\t\t\tvoid loadResults()\n\t\t}\n\t}, [hasVoted, key, loadResults, closed, resultsAwaitClose, finalized])\n\n\tconst handleSuccess = useCallback<NonNullable<FormProps['onSuccess']>>(\n\t\t(submissionId, result) => {\n\t\t\twriteVoted(key)\n\t\t\tsetVoted(true)\n\t\t\tif (!resultsAwaitClose) {\n\t\t\t\tvoid loadResults()\n\t\t\t}\n\t\t\t// Forward the resolved success response so a Poll host gets the same onSuccess payload as a Form host.\n\t\t\tonSuccess?.(submissionId, result)\n\t\t},\n\t\t[key, loadResults, onSuccess, resultsAwaitClose]\n\t)\n\n\tif (finalized) {\n\t\treturn (\n\t\t\t<div className=\"fb-poll fb-poll--final\">\n\t\t\t\t<p className=\"fb-poll__final\">{translate(keys.pollFinalResult)}</p>\n\t\t\t\t{loadFailed ? (\n\t\t\t\t\tresultsError\n\t\t\t\t) : results ? (\n\t\t\t\t\t<FormResults\n\t\t\t\t\t\tresults={results}\n\t\t\t\t\t\twinningValues={winningValues}\n\t\t\t\t\t\tt={formProps.t}\n\t\t\t\t\t\tlocale={formProps.locale}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t)\n\t}\n\n\tif (closed) {\n\t\treturn (\n\t\t\t<div className=\"fb-poll fb-poll--closed\">\n\t\t\t\t<p className=\"fb-poll__closed\">{translate(keys.pollClosed)}</p>\n\t\t\t\t{loadFailed ? (\n\t\t\t\t\tresultsError\n\t\t\t\t) : results ? (\n\t\t\t\t\t<FormResults results={results} t={formProps.t} locale={formProps.locale} />\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t)\n\t}\n\n\tif (voted) {\n\t\tif (resultsAwaitClose) {\n\t\t\treturn <p className=\"fb-poll__await-close\">{translate(keys.pollResultsAfterClose)}</p>\n\t\t}\n\t\tif (loadFailed) {\n\t\t\treturn resultsError\n\t\t}\n\t\treturn results ? (\n\t\t\t<FormResults results={results} t={formProps.t} locale={formProps.locale} />\n\t\t) : null\n\t}\n\n\treturn <Form {...formProps} apiRoute={apiRoute} onSuccess={handleSuccess} />\n}\n"],"mappings":";;;;;;;;;;;AA8BA,MAAM,aAAa,QAAyB;CAC3C,IAAI;EACH,OAAO,OAAO,aAAa,QAAQ,GAAG,KAAK;CAC5C,QAAQ;EACP,OAAO;CACR;AACD;AAEA,MAAM,cAAc,QAAsB;CACzC,IAAI;EACH,OAAO,aAAa,QAAQ,KAAK,GAAG;CACrC,QAAQ,CAER;AACD;;;;;;;;;;;;;AAcA,MAAa,QAAQ,EACpB,cACA,YACA,UACA,mBAAmB,kBACnB,UACA,WACA,GAAG,gBACa;CAChB,MAAM,MAAM,cAAc,WAAW,UAAU,KAAK;CACpD,MAAM,OAAO,UAAU,KAAK;CAC5B,MAAM,SAAS,aAAa,IAAI;CAChC,MAAM,gBAAgB,MAAM,SAAS;CACrC,MAAM,YAAY,MAAM,QAAQ,aAAa,KAAK,cAAc,SAAS;CACzE,MAAM,oBAAoB,CAAC,UAAU,CAAC,aAAa,MAAM,sBAAsB;CAC/E,MAAM,CAAC,OAAO,YAAY,SAAS,KAAK;CACxC,MAAM,CAAC,SAAS,cAAc,SAAoC,IAAI;CACtE,MAAM,CAAC,YAAY,iBAAiB,SAAS,KAAK;CAClD,MAAM,YAAY,cAAc,UAAU,KAAK,cAAc,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;CAE/E,MAAM,cAAc,YAAY,YAAY;EAC3C,MAAM,SAA6B,MAAM,iBAAiB;GACzD,QAAQ,UAAU,KAAK;GACvB,OAAO;GACP;EACD,CAAC;EAED,IAAI,OAAO,IAAI;GACd,WAAW,OAAO,OAAO;GACzB,cAAc,KAAK;EACpB,OACC,cAAc,IAAI;CAEpB,GAAG;EAAC;EAAkB,UAAU,KAAK;EAAI;EAAc;CAAQ,CAAC;CAEhE,MAAM,eACL,oBAAC,KAAD;EAAG,WAAU;EAAiB,MAAK;YACjC,UAAU,KAAK,gBAAgB;CAC9B,CAAA;CAGJ,gBAAgB;EACf,MAAM,UAAU,aAAa,QAAQ,UAAU,GAAG;EAClD,IAAI,SACH,SAAS,IAAI;EAEd,IAAK,WAAW,CAAC,qBAAsB,UAAU,WAChD,YAAiB;CAEnB,GAAG;EAAC;EAAU;EAAK;EAAa;EAAQ;EAAmB;CAAS,CAAC;CAErE,MAAM,gBAAgB,aACpB,cAAc,WAAW;EACzB,WAAW,GAAG;EACd,SAAS,IAAI;EACb,IAAI,CAAC,mBACJ,YAAiB;EAGlB,YAAY,cAAc,MAAM;CACjC,GACA;EAAC;EAAK;EAAa;EAAW;CAAiB,CAChD;CAEA,IAAI,WACH,OACC,qBAAC,OAAD;EAAK,WAAU;YAAf,CACC,oBAAC,KAAD;GAAG,WAAU;aAAkB,UAAU,KAAK,eAAe;EAAK,CAAA,GACjE,aACA,eACG,UACH,oBAAC,aAAD;GACU;GACM;GACf,GAAG,UAAU;GACb,QAAQ,UAAU;EAClB,CAAA,IACE,IACA;;CAIP,IAAI,QACH,OACC,qBAAC,OAAD;EAAK,WAAU;YAAf,CACC,oBAAC,KAAD;GAAG,WAAU;aAAmB,UAAU,KAAK,UAAU;EAAK,CAAA,GAC7D,aACA,eACG,UACH,oBAAC,aAAD;GAAsB;GAAS,GAAG,UAAU;GAAG,QAAQ,UAAU;EAAS,CAAA,IACvE,IACA;;CAIP,IAAI,OAAO;EACV,IAAI,mBACH,OAAO,oBAAC,KAAD;GAAG,WAAU;aAAwB,UAAU,KAAK,qBAAqB;EAAK,CAAA;EAEtF,IAAI,YACH,OAAO;EAER,OAAO,UACN,oBAAC,aAAD;GAAsB;GAAS,GAAG,UAAU;GAAG,QAAQ,UAAU;EAAS,CAAA,IACvE;CACL;CAEA,OAAO,oBAAC,MAAD;EAAM,GAAI;EAAqB;EAAU,WAAW;CAAgB,CAAA;AAC5E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { CaptchaWidgetHandle } from "./types.js";
|
|
2
|
+
import { Ref } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/react/captcha/HcaptchaCaptcha.d.ts
|
|
5
|
+
declare const HCAPTCHA_SCRIPT_URL = "https://js.hcaptcha.com/1/api.js?render=explicit";
|
|
6
|
+
type HcaptchaCaptchaProps = {
|
|
7
|
+
/** hCaptcha site key (public). */siteKey: string; /** Receives each fresh token, and null when the token expires or errors. */
|
|
8
|
+
onToken: (token: string | null) => void; /** Extra vendor render params (theme, size, ...). */
|
|
9
|
+
options?: Record<string, unknown>;
|
|
10
|
+
className?: string; /** Override the vendor script URL. */
|
|
11
|
+
scriptSrc?: string;
|
|
12
|
+
ref?: Ref<CaptchaWidgetHandle>;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Headless hCaptcha widget: loads the vendor script once, renders the widget into a bare div,
|
|
16
|
+
* and reports tokens through `onToken`. Pass the latest token to `<Form captchaToken>`.
|
|
17
|
+
*/
|
|
18
|
+
declare const HcaptchaCaptcha: ({
|
|
19
|
+
siteKey,
|
|
20
|
+
onToken,
|
|
21
|
+
options,
|
|
22
|
+
className,
|
|
23
|
+
scriptSrc,
|
|
24
|
+
ref
|
|
25
|
+
}: HcaptchaCaptchaProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { HCAPTCHA_SCRIPT_URL, HcaptchaCaptcha, HcaptchaCaptchaProps };
|
|
28
|
+
//# sourceMappingURL=HcaptchaCaptcha.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCaptchaScript } from "./useCaptchaScript.js";
|
|
3
|
+
import { getHcaptcha } from "./vendors.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { useEffect, useImperativeHandle, useRef } from "react";
|
|
6
|
+
//#region src/react/captcha/HcaptchaCaptcha.tsx
|
|
7
|
+
const HCAPTCHA_SCRIPT_URL = "https://js.hcaptcha.com/1/api.js?render=explicit";
|
|
8
|
+
/**
|
|
9
|
+
* Headless hCaptcha widget: loads the vendor script once, renders the widget into a bare div,
|
|
10
|
+
* and reports tokens through `onToken`. Pass the latest token to `<Form captchaToken>`.
|
|
11
|
+
*/
|
|
12
|
+
const HcaptchaCaptcha = ({ siteKey, onToken, options, className, scriptSrc = HCAPTCHA_SCRIPT_URL, ref }) => {
|
|
13
|
+
const containerRef = useRef(null);
|
|
14
|
+
const widgetIdRef = useRef(null);
|
|
15
|
+
const onTokenRef = useRef(onToken);
|
|
16
|
+
onTokenRef.current = onToken;
|
|
17
|
+
const optionsRef = useRef(options);
|
|
18
|
+
optionsRef.current = options;
|
|
19
|
+
const ready = useCaptchaScript(scriptSrc);
|
|
20
|
+
useImperativeHandle(ref, () => ({ reset: () => {
|
|
21
|
+
const api = getHcaptcha();
|
|
22
|
+
if (api && widgetIdRef.current !== null) api.reset(widgetIdRef.current);
|
|
23
|
+
onTokenRef.current(null);
|
|
24
|
+
} }), []);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!ready) return;
|
|
27
|
+
const container = containerRef.current;
|
|
28
|
+
const api = getHcaptcha();
|
|
29
|
+
if (!container || !api) return;
|
|
30
|
+
const widgetId = api.render(container, {
|
|
31
|
+
...optionsRef.current,
|
|
32
|
+
sitekey: siteKey,
|
|
33
|
+
callback: (token) => onTokenRef.current(token),
|
|
34
|
+
"expired-callback": () => onTokenRef.current(null),
|
|
35
|
+
"error-callback": () => onTokenRef.current(null)
|
|
36
|
+
});
|
|
37
|
+
widgetIdRef.current = widgetId;
|
|
38
|
+
return () => {
|
|
39
|
+
widgetIdRef.current = null;
|
|
40
|
+
try {
|
|
41
|
+
api.remove(widgetId);
|
|
42
|
+
} catch {}
|
|
43
|
+
};
|
|
44
|
+
}, [ready, siteKey]);
|
|
45
|
+
return /* @__PURE__ */ jsx("div", {
|
|
46
|
+
ref: containerRef,
|
|
47
|
+
className
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
51
|
+
export { HCAPTCHA_SCRIPT_URL, HcaptchaCaptcha };
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=HcaptchaCaptcha.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HcaptchaCaptcha.js","names":[],"sources":["../../../src/react/captcha/HcaptchaCaptcha.tsx"],"sourcesContent":["'use client'\n\nimport { type Ref, useEffect, useImperativeHandle, useRef } from 'react'\nimport type { CaptchaWidgetHandle } from './types'\nimport { useCaptchaScript } from './useCaptchaScript'\nimport { getHcaptcha } from './vendors'\n\nexport const HCAPTCHA_SCRIPT_URL = 'https://js.hcaptcha.com/1/api.js?render=explicit'\n\nexport type HcaptchaCaptchaProps = {\n\t/** hCaptcha site key (public). */\n\tsiteKey: string\n\t/** Receives each fresh token, and null when the token expires or errors. */\n\tonToken: (token: string | null) => void\n\t/** Extra vendor render params (theme, size, ...). */\n\toptions?: Record<string, unknown>\n\tclassName?: string\n\t/** Override the vendor script URL. */\n\tscriptSrc?: string\n\tref?: Ref<CaptchaWidgetHandle>\n}\n\n/**\n * Headless hCaptcha widget: loads the vendor script once, renders the widget into a bare div,\n * and reports tokens through `onToken`. Pass the latest token to `<Form captchaToken>`.\n */\nexport const HcaptchaCaptcha = ({\n\tsiteKey,\n\tonToken,\n\toptions,\n\tclassName,\n\tscriptSrc = HCAPTCHA_SCRIPT_URL,\n\tref,\n}: HcaptchaCaptchaProps) => {\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst widgetIdRef = useRef<string | null>(null)\n\tconst onTokenRef = useRef(onToken)\n\tonTokenRef.current = onToken\n\tconst optionsRef = useRef(options)\n\toptionsRef.current = options\n\tconst ready = useCaptchaScript(scriptSrc)\n\n\tuseImperativeHandle(\n\t\tref,\n\t\t() => ({\n\t\t\treset: () => {\n\t\t\t\tconst api = getHcaptcha()\n\t\t\t\tif (api && widgetIdRef.current !== null) {\n\t\t\t\t\tapi.reset(widgetIdRef.current)\n\t\t\t\t}\n\t\t\t\tonTokenRef.current(null)\n\t\t\t},\n\t\t}),\n\t\t[]\n\t)\n\n\tuseEffect(() => {\n\t\tif (!ready) {\n\t\t\treturn\n\t\t}\n\t\tconst container = containerRef.current\n\t\tconst api = getHcaptcha()\n\t\tif (!container || !api) {\n\t\t\treturn\n\t\t}\n\t\tconst widgetId = api.render(container, {\n\t\t\t...optionsRef.current,\n\t\t\tsitekey: siteKey,\n\t\t\tcallback: (token: string) => onTokenRef.current(token),\n\t\t\t'expired-callback': () => onTokenRef.current(null),\n\t\t\t'error-callback': () => onTokenRef.current(null),\n\t\t})\n\t\twidgetIdRef.current = widgetId\n\t\treturn () => {\n\t\t\twidgetIdRef.current = null\n\t\t\ttry {\n\t\t\t\tapi.remove(widgetId)\n\t\t\t} catch {}\n\t\t}\n\t}, [ready, siteKey])\n\n\treturn <div ref={containerRef} className={className} />\n}\n"],"mappings":";;;;;;AAOA,MAAa,sBAAsB;;;;;AAmBnC,MAAa,mBAAmB,EAC/B,SACA,SACA,SACA,WACA,YAAY,qBACZ,UAC2B;CAC3B,MAAM,eAAe,OAAuB,IAAI;CAChD,MAAM,cAAc,OAAsB,IAAI;CAC9C,MAAM,aAAa,OAAO,OAAO;CACjC,WAAW,UAAU;CACrB,MAAM,aAAa,OAAO,OAAO;CACjC,WAAW,UAAU;CACrB,MAAM,QAAQ,iBAAiB,SAAS;CAExC,oBACC,YACO,EACN,aAAa;EACZ,MAAM,MAAM,YAAY;EACxB,IAAI,OAAO,YAAY,YAAY,MAClC,IAAI,MAAM,YAAY,OAAO;EAE9B,WAAW,QAAQ,IAAI;CACxB,EACD,IACA,CAAC,CACF;CAEA,gBAAgB;EACf,IAAI,CAAC,OACJ;EAED,MAAM,YAAY,aAAa;EAC/B,MAAM,MAAM,YAAY;EACxB,IAAI,CAAC,aAAa,CAAC,KAClB;EAED,MAAM,WAAW,IAAI,OAAO,WAAW;GACtC,GAAG,WAAW;GACd,SAAS;GACT,WAAW,UAAkB,WAAW,QAAQ,KAAK;GACrD,0BAA0B,WAAW,QAAQ,IAAI;GACjD,wBAAwB,WAAW,QAAQ,IAAI;EAChD,CAAC;EACD,YAAY,UAAU;EACtB,aAAa;GACZ,YAAY,UAAU;GACtB,IAAI;IACH,IAAI,OAAO,QAAQ;GACpB,QAAQ,CAAC;EACV;CACD,GAAG,CAAC,OAAO,OAAO,CAAC;CAEnB,OAAO,oBAAC,OAAD;EAAK,KAAK;EAAyB;CAAY,CAAA;AACvD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { CaptchaWidgetHandle } from "./types.js";
|
|
2
|
+
import { Ref } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/react/captcha/RecaptchaCaptcha.d.ts
|
|
5
|
+
declare const RECAPTCHA_SCRIPT_URL = "https://www.google.com/recaptcha/api.js";
|
|
6
|
+
type RecaptchaCaptchaHandle = CaptchaWidgetHandle & {
|
|
7
|
+
/**
|
|
8
|
+
* v3 only: fetch a fresh token on demand and report it through `onToken`. v3 tokens expire
|
|
9
|
+
* after about two minutes, so call this right before submit for a long-lived form. Resolves
|
|
10
|
+
* null for v2 or when execution fails.
|
|
11
|
+
*/
|
|
12
|
+
execute: (action?: string) => Promise<string | null>;
|
|
13
|
+
};
|
|
14
|
+
type RecaptchaCaptchaProps = {
|
|
15
|
+
/** reCAPTCHA site key (public). */siteKey: string; /** 'v2' renders the checkbox widget; 'v3' runs invisibly and produces score-based tokens. */
|
|
16
|
+
version: 'v2' | 'v3'; /** v3 action name reported to reCAPTCHA. Default 'submit'. */
|
|
17
|
+
action?: string; /** Receives each fresh token, and null when the token expires, errors, or is reset. */
|
|
18
|
+
onToken: (token: string | null) => void; /** Extra vendor render params for v2 (theme, size, ...). */
|
|
19
|
+
options?: Record<string, unknown>;
|
|
20
|
+
className?: string; /** Override the vendor script URL (the version-specific `render` query is not appended). */
|
|
21
|
+
scriptSrc?: string;
|
|
22
|
+
ref?: Ref<RecaptchaCaptchaHandle>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Headless Google reCAPTCHA widget for v2 (checkbox) and v3 (invisible, score-based). v2 reports
|
|
26
|
+
* tokens as the user solves the challenge; v3 fetches an initial token on mount and exposes
|
|
27
|
+
* `execute` on the ref for on-demand refresh. Pass the latest token to `<Form captchaToken>`.
|
|
28
|
+
*/
|
|
29
|
+
declare const RecaptchaCaptcha: ({
|
|
30
|
+
siteKey,
|
|
31
|
+
version,
|
|
32
|
+
action,
|
|
33
|
+
onToken,
|
|
34
|
+
options,
|
|
35
|
+
className,
|
|
36
|
+
scriptSrc,
|
|
37
|
+
ref
|
|
38
|
+
}: RecaptchaCaptchaProps) => import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { RECAPTCHA_SCRIPT_URL, RecaptchaCaptcha, RecaptchaCaptchaHandle, RecaptchaCaptchaProps };
|
|
41
|
+
//# sourceMappingURL=RecaptchaCaptcha.d.ts.map
|