@alfadocs/ui-kit-debug 1.78.0 → 1.79.0
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/dist/_chunks/{address-fields-BUPRs3n-.js → address-fields-GnoSkvh6.js} +2 -2
- package/dist/_chunks/{address-fields-BUPRs3n-.js.map → address-fields-GnoSkvh6.js.map} +1 -1
- package/dist/_chunks/{anamnesis-summary-rows-vNDyE5HW.js → anamnesis-summary-rows-lONg-zja.js} +2 -2
- package/dist/_chunks/{anamnesis-summary-rows-vNDyE5HW.js.map → anamnesis-summary-rows-lONg-zja.js.map} +1 -1
- package/dist/_chunks/{bishop-score-CdbU9Nl4.js → bishop-score-C5di6oAV.js} +2 -2
- package/dist/_chunks/{bishop-score-CdbU9Nl4.js.map → bishop-score-C5di6oAV.js.map} +1 -1
- package/dist/_chunks/{bmi-calculator-DnfiDh4Q.js → bmi-calculator-BIExHBZV.js} +2 -2
- package/dist/_chunks/{bmi-calculator-DnfiDh4Q.js.map → bmi-calculator-BIExHBZV.js.map} +1 -1
- package/dist/_chunks/{booking-Cz_QjIJe.js → booking-BV2s2J3C.js} +3 -3
- package/dist/_chunks/{booking-Cz_QjIJe.js.map → booking-BV2s2J3C.js.map} +1 -1
- package/dist/_chunks/{calendar-appointment-editor-dialog-cvUpUjj-.js → calendar-appointment-editor-dialog-DhTTWgXw.js} +3 -3
- package/dist/_chunks/{calendar-appointment-editor-dialog-cvUpUjj-.js.map → calendar-appointment-editor-dialog-DhTTWgXw.js.map} +1 -1
- package/dist/_chunks/{cycle-calculator-HO3s5InI.js → cycle-calculator-CQkjVSD2.js} +2 -2
- package/dist/_chunks/{cycle-calculator-HO3s5InI.js.map → cycle-calculator-CQkjVSD2.js.map} +1 -1
- package/dist/_chunks/{due-date-calculator-CDWTSblh.js → due-date-calculator-NjTlmoFK.js} +2 -2
- package/dist/_chunks/{due-date-calculator-CDWTSblh.js.map → due-date-calculator-NjTlmoFK.js.map} +1 -1
- package/dist/_chunks/{fetal-weight-CrtBFJl-.js → fetal-weight-Brl3n4LN.js} +2 -2
- package/dist/_chunks/{fetal-weight-CrtBFJl-.js.map → fetal-weight-Brl3n4LN.js.map} +1 -1
- package/dist/_chunks/{forgot-password-form-BSOZVrZG.js → forgot-password-form-BQPvDS7i.js} +2 -2
- package/dist/_chunks/{forgot-password-form-BSOZVrZG.js.map → forgot-password-form-BQPvDS7i.js.map} +1 -1
- package/dist/_chunks/form-field-CyHfOVKF.js +185 -0
- package/dist/_chunks/form-field-CyHfOVKF.js.map +1 -0
- package/dist/_chunks/{gestational-age-calculator-CTHeJJdb.js → gestational-age-calculator-Dr9hdDta.js} +2 -2
- package/dist/_chunks/{gestational-age-calculator-CTHeJJdb.js.map → gestational-age-calculator-Dr9hdDta.js.map} +1 -1
- package/dist/_chunks/{hcg-doubling-BBk-a33g.js → hcg-doubling-K41Wy7LB.js} +2 -2
- package/dist/_chunks/{hcg-doubling-BBk-a33g.js.map → hcg-doubling-K41Wy7LB.js.map} +1 -1
- package/dist/_chunks/{help-me-write-templates-Ds1FY-WY.js → help-me-write-templates-BJSf24xS.js} +2 -2
- package/dist/_chunks/{help-me-write-templates-Ds1FY-WY.js.map → help-me-write-templates-BJSf24xS.js.map} +1 -1
- package/dist/_chunks/key-round-DIgsnJSg.js +21 -0
- package/dist/_chunks/key-round-DIgsnJSg.js.map +1 -0
- package/dist/_chunks/{kit-extensions-sNTZWkoo.js → kit-extensions-a0G4COFH.js} +6 -6
- package/dist/_chunks/{kit-extensions-sNTZWkoo.js.map → kit-extensions-a0G4COFH.js.map} +1 -1
- package/dist/_chunks/login-dev-card-CvLHj-_N.js +353 -0
- package/dist/_chunks/login-dev-card-CvLHj-_N.js.map +1 -0
- package/dist/_chunks/{pregnancy-dating-JBAUbM40.js → pregnancy-dating-BHvfDxz4.js} +2 -2
- package/dist/_chunks/{pregnancy-dating-JBAUbM40.js.map → pregnancy-dating-BHvfDxz4.js.map} +1 -1
- package/dist/_chunks/{pregnancy-weight-gain--Bqv6AWu.js → pregnancy-weight-gain-BeQRxwdP.js} +2 -2
- package/dist/_chunks/{pregnancy-weight-gain--Bqv6AWu.js.map → pregnancy-weight-gain-BeQRxwdP.js.map} +1 -1
- package/dist/_chunks/{radiograph-panel.agent-DQh2SX8G.js → radiograph-panel.agent-BQ95uFCd.js} +2 -2
- package/dist/_chunks/{radiograph-panel.agent-DQh2SX8G.js.map → radiograph-panel.agent-BQ95uFCd.js.map} +1 -1
- package/dist/_chunks/registration-form-CNBfUduG.js +1337 -0
- package/dist/_chunks/registration-form-CNBfUduG.js.map +1 -0
- package/dist/_chunks/reset-password-form-Cf9QPEJu.js +367 -0
- package/dist/_chunks/reset-password-form-Cf9QPEJu.js.map +1 -0
- package/dist/_chunks/{send-registration-link-form-__DWY62q.js → send-registration-link-form-vTn1HxjA.js} +2 -2
- package/dist/_chunks/{send-registration-link-form-__DWY62q.js.map → send-registration-link-form-vTn1HxjA.js.map} +1 -1
- package/dist/_chunks/{task-editor-CRhfwP9T.js → task-editor-Cpw-NmND.js} +2 -2
- package/dist/_chunks/{task-editor-CRhfwP9T.js.map → task-editor-Cpw-NmND.js.map} +1 -1
- package/dist/_chunks/{unit-converter-D59L-gkf.js → unit-converter-BH5ueIhT.js} +2 -2
- package/dist/_chunks/{unit-converter-D59L-gkf.js.map → unit-converter-BH5ueIhT.js.map} +1 -1
- package/dist/_chunks/{voice-control-panel-DQJwe6_Q.js → voice-control-panel-BziKE-KK.js} +2 -2
- package/dist/_chunks/{voice-control-panel-DQJwe6_Q.js.map → voice-control-panel-BziKE-KK.js.map} +1 -1
- package/dist/_chunks/{workflow-webhook-action-BvVPZVpG.js → workflow-webhook-action-DulCpCRz.js} +96 -111
- package/dist/_chunks/workflow-webhook-action-DulCpCRz.js.map +1 -0
- package/dist/agent-catalog.json +89 -3
- package/dist/agent-i18n/en.json +11 -2
- package/dist/components/address-fields/index.js +1 -1
- package/dist/components/bishop-score/index.js +1 -1
- package/dist/components/bmi-calculator/index.js +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/cycle-calculator/index.js +1 -1
- package/dist/components/due-date-calculator/index.js +1 -1
- package/dist/components/fetal-weight/index.js +1 -1
- package/dist/components/form-field/form-field.d.ts +6 -0
- package/dist/components/form-field/form-field.d.ts.map +1 -1
- package/dist/components/form-field/index.js +1 -1
- package/dist/components/gestational-age-calculator/index.js +1 -1
- package/dist/components/hcg-doubling/index.js +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/pregnancy-dating/index.js +1 -1
- package/dist/components/pregnancy-weight-gain/index.js +1 -1
- package/dist/components/radiograph-panel/index.js +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/task-editor/index.js +1 -1
- package/dist/components/unit-converter/index.js +1 -1
- package/dist/components/voice-control-panel/index.js +1 -1
- package/dist/i18n/locales/ar.d.ts +26 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +27 -1
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +26 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +27 -1
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +26 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +27 -1
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +26 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +26 -0
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +26 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +27 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +26 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +27 -1
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +26 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +27 -1
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +26 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +27 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +26 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +27 -1
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +26 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +27 -1
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +26 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +27 -1
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +26 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +27 -1
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +26 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +27 -1
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +26 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +27 -1
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +26 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +27 -1
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +26 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +27 -1
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +26 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +27 -1
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +26 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +27 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +89 -86
- package/dist/index.js.map +1 -1
- package/dist/locales/ar.json +27 -1
- package/dist/locales/de.json +27 -1
- package/dist/locales/el.json +27 -1
- package/dist/locales/en.json +26 -0
- package/dist/locales/es.json +27 -1
- package/dist/locales/fr.json +27 -1
- package/dist/locales/hi.json +27 -1
- package/dist/locales/it.json +27 -1
- package/dist/locales/ja.json +27 -1
- package/dist/locales/nl.json +27 -1
- package/dist/locales/pl.json +27 -1
- package/dist/locales/pt.json +27 -1
- package/dist/locales/ro.json +27 -1
- package/dist/locales/ru.json +27 -1
- package/dist/locales/sq.json +27 -1
- package/dist/locales/sv.json +27 -1
- package/dist/locales/tr.json +27 -1
- package/dist/locales/zh.json +27 -1
- package/dist/patterns/_shared/password-policy.d.ts +3 -0
- package/dist/patterns/_shared/password-policy.d.ts.map +1 -0
- package/dist/patterns/anamnesis/index.js +1 -1
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/patterns/forgot-password-form/index.js +1 -1
- package/dist/patterns/help-me-write-templates/index.js +1 -1
- package/dist/patterns/login-form/index.js +1 -1
- package/dist/patterns/login-form/login-form.d.ts +24 -7
- package/dist/patterns/login-form/login-form.d.ts.map +1 -1
- package/dist/patterns/registration-form/index.d.ts +1 -1
- package/dist/patterns/registration-form/index.d.ts.map +1 -1
- package/dist/patterns/registration-form/index.js +1 -1
- package/dist/patterns/registration-form/registration-form.d.ts +27 -0
- package/dist/patterns/registration-form/registration-form.d.ts.map +1 -1
- package/dist/patterns/reset-password-form/index.d.ts +3 -0
- package/dist/patterns/reset-password-form/index.d.ts.map +1 -0
- package/dist/patterns/reset-password-form/index.js +6 -0
- package/dist/patterns/reset-password-form/index.js.map +1 -0
- package/dist/patterns/reset-password-form/reset-password-form.d.ts +108 -0
- package/dist/patterns/reset-password-form/reset-password-form.d.ts.map +1 -0
- package/dist/patterns/send-registration-link-form/index.js +1 -1
- package/dist/patterns/workflow-webhook-action/index.js +1 -1
- package/package.json +5 -1
- package/dist/_chunks/form-field-Ani72sVY.js +0 -176
- package/dist/_chunks/form-field-Ani72sVY.js.map +0 -1
- package/dist/_chunks/login-dev-card-DRxTPkE9.js +0 -332
- package/dist/_chunks/login-dev-card-DRxTPkE9.js.map +0 -1
- package/dist/_chunks/registration-form-xORq2s4p.js +0 -1310
- package/dist/_chunks/registration-form-xORq2s4p.js.map +0 -1
- package/dist/_chunks/workflow-webhook-action-BvVPZVpG.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"registration-form-xORq2s4p.js","sources":["../../src/patterns/registration-form/verification-requests.ts","../../src/patterns/registration-form/use-contact-verification.ts","../../src/patterns/registration-form/registration-verification.tsx","../../src/patterns/registration-form/registration-form.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Data-only verification: the kit sends the two requests itself. */\n/* */\n/* A host that renders the form from JSON cannot pass functions. It */\n/* passes `sendUrl` and `verifyUrl`; this file turns them into the two */\n/* callbacks the state machine already takes. */\n/* -------------------------------------------------------------------- */\n\nimport { isDevelopment } from '../../components/_shared/is-development';\nimport { isSameSiteHref } from '../../components/_shared/safe-href';\nimport type {\n RegistrationCodeFailure,\n RegistrationCodeResult,\n RegistrationFieldVerification,\n} from './use-contact-verification';\n\nconst FAILURES: readonly RegistrationCodeFailure[] = [\n 'invalid',\n 'expired',\n 'rate_limited',\n 'error',\n];\n\nconst FAILED: RegistrationCodeResult = { ok: false, reason: 'error' };\n\nconst positiveNumber = (input: unknown): number | undefined =>\n typeof input === 'number' && Number.isFinite(input) && input >= 0\n ? input\n : undefined;\n\n/** Keeps only the fields of a result that the kit reads. */\nfunction toResult(body: unknown): RegistrationCodeResult | null {\n if (typeof body !== 'object' || body === null) return null;\n const raw = body as Record<string, unknown>;\n if (typeof raw.ok !== 'boolean') return null;\n const result: RegistrationCodeResult = { ok: raw.ok };\n if (typeof raw.message === 'string') result.message = raw.message;\n if (FAILURES.includes(raw.reason as RegistrationCodeFailure)) {\n result.reason = raw.reason as RegistrationCodeFailure;\n }\n const retry = positiveNumber(raw.retryAfterSeconds);\n if (retry !== undefined) result.retryAfterSeconds = retry;\n const resend = positiveNumber(raw.resendAfterSeconds);\n if (resend !== undefined) result.resendAfterSeconds = resend;\n if (typeof raw.devCode === 'string') result.devCode = raw.devCode;\n if (typeof raw.value === 'string') result.value = raw.value;\n return result;\n}\n\n/** Seconds from a `Retry-After` header; a date form is not read. */\nfunction retryAfterHeader(response: Response): number | undefined {\n const header = response.headers.get('Retry-After');\n if (!header || !/^\\d+$/.test(header.trim())) return undefined;\n return Number(header.trim());\n}\n\n/** Posts JSON to a path or same-origin URL. Never rejects. */\nexport async function postVerification(\n url: string,\n payload: Record<string, string>,\n): Promise<RegistrationCodeResult> {\n if (!isSameSiteHref(url)) {\n if (isDevelopment()) {\n console.warn(\n `RegistrationForm: verification URL \"${url}\" is not a path or an address on this site, so no request was sent.`,\n );\n }\n return FAILED;\n }\n try {\n const response = await fetch(url, {\n method: 'POST',\n credentials: 'same-origin',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'X-Requested-With': 'XMLHttpRequest',\n },\n body: JSON.stringify(payload),\n });\n const limited = response.status === 429;\n // The answer travels in the body on success and on failure; a server\n // error page is not one.\n if (!limited && (response.status < 200 || response.status >= 500)) {\n return FAILED;\n }\n let body: unknown = null;\n try {\n body = await response.json();\n } catch {\n body = null;\n }\n const result = toResult(body);\n if (limited) {\n const base: RegistrationCodeResult = result ?? { ok: false };\n const retry =\n base.retryAfterSeconds ?? retryAfterHeader(response) ?? undefined;\n return {\n ...base,\n ok: false,\n reason: 'rate_limited',\n ...(retry !== undefined ? { retryAfterSeconds: retry } : {}),\n };\n }\n if (!result) return FAILED;\n // A refusal needs a reason; an answer of success on an error status\n // is not trusted.\n if (response.status >= 400) {\n return result.ok\n ? FAILED\n : { ...result, reason: result.reason ?? 'error' };\n }\n return result;\n } catch {\n return FAILED;\n }\n}\n\n/** The two callbacks for a field, whichever way the host configured it. */\nexport function verificationHandlers(config: RegistrationFieldVerification): {\n onSendCode: (value: string) => Promise<RegistrationCodeResult>;\n onVerifyCode: (\n value: string,\n code: string,\n ) => Promise<RegistrationCodeResult>;\n} {\n if ('sendUrl' in config && config.sendUrl !== undefined) {\n const { sendUrl, verifyUrl } = config;\n return {\n onSendCode: (value) => postVerification(sendUrl, { value }),\n onVerifyCode: (value, code) =>\n postVerification(verifyUrl, { value, code }),\n };\n }\n return {\n onSendCode: config.onSendCode as (\n value: string,\n ) => Promise<RegistrationCodeResult>,\n onVerifyCode: config.onVerifyCode as (\n value: string,\n code: string,\n ) => Promise<RegistrationCodeResult>,\n };\n}\n","/* -------------------------------------------------------------------- */\n/* useContactVerification: the state of one field's \"prove it with a */\n/* code\" step in the registration form. */\n/* */\n/* idle -> sending -> sent -> verifying -> verified. There is no way */\n/* back from verified: the server holds the verified value. A change to */\n/* the value before that sends the field back to idle. */\n/* */\n/* Shipped with RegistrationForm; not an export of its own. */\n/* -------------------------------------------------------------------- */\n\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { verificationHandlers } from './verification-requests';\n\n/** The fields that can be verified by a code. */\nexport type RegistrationVerifiableField = 'email' | 'phone';\n\n/** Why a send or a check failed. */\nexport type RegistrationCodeFailure =\n | 'invalid'\n | 'expired'\n | 'rate_limited'\n | 'error';\n\n/** What the host answers when a code is sent or checked. */\nexport interface RegistrationCodeResult {\n ok: boolean;\n /** Already translated by the host. Shown under the field when `ok` is\n * false, instead of the kit's own wording for `reason`. */\n message?: string;\n reason?: RegistrationCodeFailure;\n /** With `rate_limited`: seconds before another send is allowed. */\n retryAfterSeconds?: number;\n /** After a send: seconds before \"Send a new code\" works. Default 30. */\n resendAfterSeconds?: number;\n /** Development only. The host passes it only when its server says this\n * is a development environment; it shows in an info alert. */\n devCode?: string;\n /** After a check: the value the server verified. Informational. */\n value?: string;\n}\n\n/** Options both ways of verifying a field share. */\nexport interface RegistrationFieldVerificationOptions {\n /** Digits in the code. Default 6. */\n codeLength?: number;\n /** True when the server already holds this value as verified, such as\n * a page that reopens after a refused post. */\n verified?: boolean;\n /**\n * With `verified`: the person may still change the value. The field\n * shows as verified with a \"Change\" action; pressing it unlocks the\n * field. Typing back exactly the value that started verified (trimmed,\n * case ignored) is verified again with no code; any other value needs\n * a code. Without it, `verified` locks the field with no way back.\n * A plain boolean, so it works from JSON.\n */\n allowChange?: boolean;\n /** Called with `true` once the code is right. */\n onVerifiedChange?: (verified: boolean) => void;\n}\n\n/** Callbacks: for a React host that calls its own API. */\nexport interface RegistrationFieldVerificationCallbacks extends RegistrationFieldVerificationOptions {\n /** Sends a code to the value. Resolve, never reject: a rejection is\n * shown as a failure with reason `error`. */\n onSendCode: (value: string) => Promise<RegistrationCodeResult>;\n /** Checks the code the person typed for the value. */\n onVerifyCode: (\n value: string,\n code: string,\n ) => Promise<RegistrationCodeResult>;\n sendUrl?: never;\n verifyUrl?: never;\n}\n\n/**\n * URLs: data only, for a host that mounts the form from JSON. The kit\n * POSTs JSON to each (same origin, cookies sent). Send body:\n * `{ \"value\" }`. Verify body: `{ \"value\", \"code\" }`. The answer is a\n * `RegistrationCodeResult` as JSON, on success and on failure. A path or\n * an address on this site only.\n */\nexport interface RegistrationFieldVerificationUrls extends RegistrationFieldVerificationOptions {\n sendUrl: string;\n verifyUrl: string;\n onSendCode?: never;\n onVerifyCode?: never;\n}\n\n/** How one field is verified: both callbacks, or both URLs. */\nexport type RegistrationFieldVerification =\n | RegistrationFieldVerificationCallbacks\n | RegistrationFieldVerificationUrls;\n\nexport type ContactVerificationStatus =\n | 'idle'\n | 'sending'\n | 'sent'\n | 'verifying'\n | 'verified';\n\nexport interface ContactVerificationFailure {\n reason: RegistrationCodeFailure;\n /** The host's own message, when it gave one. */\n message?: string;\n}\n\nexport const DEFAULT_CODE_LENGTH = 6;\nexport const DEFAULT_RESEND_SECONDS = 30;\n\nconst failureOf = (\n result: RegistrationCodeResult,\n): ContactVerificationFailure => ({\n reason: result.reason ?? 'error',\n message: result.message,\n});\n\nexport interface UseContactVerificationOptions {\n /** Undefined: the field is not verified and the hook does nothing. */\n config: RegistrationFieldVerification | undefined;\n /** The value now in the field. */\n value: string;\n}\n\nexport interface UseContactVerificationReturn {\n /** True when the field takes part in verification. */\n enabled: boolean;\n status: ContactVerificationStatus;\n /** True once the server has accepted the value. */\n verified: boolean;\n codeLength: number;\n code: string;\n setCode: (code: string) => void;\n failure: ContactVerificationFailure | null;\n /** Seconds left before a new code may be sent; 0 when it may. */\n cooldown: number;\n devCode: string | undefined;\n /** The value the code went to. */\n sentTo: string;\n send: () => void;\n verify: (code?: string) => void;\n /** Back to idle: the person wants to change the value. */\n reset: () => void;\n /** True when the server's \"verified\" may be changed (`allowChange`)\n * and the field is verified right now. */\n changeable: boolean;\n /** Unlocks a `changeable` field so the value can be edited. */\n unlock: () => void;\n}\n\n/** Runs one field's verification step. */\nexport function useContactVerification({\n config,\n value,\n}: UseContactVerificationOptions): UseContactVerificationReturn {\n const codeLength = config?.codeLength ?? DEFAULT_CODE_LENGTH;\n const [status, setStatus] = useState<ContactVerificationStatus>('idle');\n const [code, setCodeState] = useState('');\n const [failure, setFailure] = useState<ContactVerificationFailure | null>(\n null,\n );\n const [cooldown, setCooldown] = useState(0);\n const [devCode, setDevCode] = useState<string | undefined>();\n const [sentTo, setSentTo] = useState('');\n\n // The latest config and value, so the callbacks below stay stable and\n // never act on a stale host function.\n const latest = useRef({ config, value });\n latest.current = { config, value };\n // Each send or check takes a number; an answer for an older one is\n // dropped, such as one that lands after the person changed the value.\n const request = useRef(0);\n\n // The value the host said was verified, when the page opened.\n const [original] = useState<string | null>(() =>\n config?.verified === true ? value : null,\n );\n const [unlocked, setUnlocked] = useState(false);\n const verifiedByHost = config?.verified === true && !unlocked;\n const verified = verifiedByHost || status === 'verified';\n\n // Tell the host once, when the code is right.\n const told = useRef(false);\n useEffect(() => {\n if (status === 'verified' && !told.current) {\n told.current = true;\n latest.current.config?.onVerifiedChange?.(true);\n }\n }, [status]);\n\n // One tick a second while the wait lasts.\n useEffect(() => {\n if (cooldown <= 0) return undefined;\n const timer = setTimeout(() => setCooldown((left) => left - 1), 1000);\n return () => clearTimeout(timer);\n }, [cooldown]);\n\n const sameValue = (a: string, b: string) =>\n a.trim().toLowerCase() === b.trim().toLowerCase();\n\n // Back to the verified value: verified again, no code.\n useEffect(() => {\n if (unlocked && original !== null && sameValue(value, original)) {\n setUnlocked(false);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps -- on an edit only, so pressing Change keeps the field open\n }, [value]);\n\n const reset = useCallback(() => {\n request.current += 1;\n setStatus((current) => (current === 'verified' ? current : 'idle'));\n setCodeState('');\n setFailure(null);\n setDevCode(undefined);\n setSentTo('');\n // A new value is not bound by the wait for the old one.\n setCooldown(0);\n }, []);\n\n // Editing the value after a code went out voids that code.\n useEffect(() => {\n if (status === 'verified') return;\n if (\n (status === 'sent' || status === 'verifying' || status === 'sending') &&\n value !== sentTo\n ) {\n reset();\n }\n }, [value, sentTo, status, reset]);\n\n // A failed send was about the old value.\n const lastValue = useRef(value);\n useEffect(() => {\n if (lastValue.current === value) return;\n lastValue.current = value;\n if (status === 'idle') setFailure(null);\n }, [value, status]);\n\n const send = useCallback(() => {\n const { config: current, value: target } = latest.current;\n if (!current) return;\n const id = (request.current += 1);\n setStatus('sending');\n setFailure(null);\n setCodeState('');\n setSentTo(target);\n verificationHandlers(current)\n .onSendCode(target)\n .then(\n (result) => result,\n (): RegistrationCodeResult => ({ ok: false, reason: 'error' }),\n )\n .then((result) => {\n if (id !== request.current) return;\n if (result.ok) {\n setStatus('sent');\n setDevCode(result.devCode);\n setCooldown(result.resendAfterSeconds ?? DEFAULT_RESEND_SECONDS);\n return;\n }\n setStatus('idle');\n setSentTo('');\n setFailure(failureOf(result));\n if (result.reason === 'rate_limited' && result.retryAfterSeconds) {\n setCooldown(result.retryAfterSeconds);\n }\n });\n }, []);\n\n const verify = useCallback(\n (typed?: string) => {\n const { config: current, value: target } = latest.current;\n if (!current) return;\n const length = current.codeLength ?? DEFAULT_CODE_LENGTH;\n const entered = typed ?? code;\n if (entered.length !== length) return;\n const id = (request.current += 1);\n setStatus('verifying');\n setFailure(null);\n verificationHandlers(current)\n .onVerifyCode(target, entered)\n .then(\n (result) => result,\n (): RegistrationCodeResult => ({ ok: false, reason: 'error' }),\n )\n .then((result) => {\n if (id !== request.current) return;\n if (result.ok) {\n setStatus('verified');\n setCodeState('');\n setDevCode(undefined);\n setCooldown(0);\n return;\n }\n setStatus('sent');\n setCodeState('');\n setFailure(failureOf(result));\n if (result.reason === 'rate_limited' && result.retryAfterSeconds) {\n setCooldown(result.retryAfterSeconds);\n }\n // An expired code cannot be retried: only a new one helps.\n if (result.reason === 'expired') setCooldown(0);\n });\n },\n [code],\n );\n\n const changeable = verifiedByHost && config?.allowChange === true;\n const unlock = useCallback(() => {\n request.current += 1;\n setUnlocked(true);\n setStatus('idle');\n setCodeState('');\n setFailure(null);\n setDevCode(undefined);\n setSentTo('');\n setCooldown(0);\n }, []);\n\n const setCode = useCallback((next: string) => {\n setCodeState(next);\n setFailure((current) => (current ? null : current));\n }, []);\n\n return {\n enabled: config !== undefined,\n status: verifiedByHost ? 'verified' : status,\n verified,\n codeLength,\n code,\n setCode,\n failure,\n cooldown,\n devCode,\n sentTo,\n send,\n verify,\n reset,\n changeable,\n unlock,\n };\n}\n","/* -------------------------------------------------------------------- */\n/* The pieces of RegistrationForm's \"prove it with a code\" step. */\n/* */\n/* `VerificationAction` is the button beside the field. `Verification- */\n/* Panel` sits under it: the code box while a code is out, the success */\n/* line once the code is right. Both read the state that */\n/* `useContactVerification` keeps; neither knows the host's server. */\n/* */\n/* Shipped with RegistrationForm; not an export of its own. */\n/* -------------------------------------------------------------------- */\n\nimport { useEffect, useRef, useState } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { CircleCheck, Pencil } from 'lucide-react';\nimport { Alert } from '../../components/alert';\nimport { Button } from '../../components/button';\nimport { FormField } from '../../components/form-field';\nimport { OTPInput } from '../../components/otp-input';\nimport type {\n ContactVerificationFailure,\n RegistrationVerifiableField,\n UseContactVerificationReturn,\n} from './use-contact-verification';\n\n/** The kit's own wording for a failure, when the host gave none. */\nfunction useFailureMessage(\n failure: ContactVerificationFailure | null,\n): string | undefined {\n const { t } = useTranslation('ui');\n if (!failure) return undefined;\n if (failure.message) return failure.message;\n switch (failure.reason) {\n case 'invalid':\n return t('registrationForm.verification.invalidCode');\n case 'expired':\n return t('registrationForm.verification.expiredCode');\n case 'rate_limited':\n return t('registrationForm.verification.rateLimited');\n default:\n return t('registrationForm.verification.sendFailed');\n }\n}\n\n/** The message a failed send leaves under the field. */\nexport function useSendFailureMessage(\n state: UseContactVerificationReturn,\n): string | undefined {\n const message = useFailureMessage(state.failure);\n return state.status === 'idle' ? message : undefined;\n}\n\ninterface VerificationActionProps {\n state: UseContactVerificationReturn;\n /** True when the value could be an address or a number. */\n canSend: boolean;\n}\n\n/** \"Send code\", beside the field. Gone once a code is out. */\nexport function VerificationAction({\n state,\n canSend,\n}: VerificationActionProps) {\n const { t } = useTranslation('ui');\n const sending = state.status === 'sending';\n if (state.status !== 'idle' && !sending) return null;\n const waiting = state.cooldown > 0;\n return (\n <Button\n type=\"button\"\n intent=\"secondary\"\n loading={sending}\n disabled={!canSend}\n // Not native `disabled` for the wait: focus stays on the button.\n aria-disabled={waiting || undefined}\n data-action=\"send-code\"\n className=\"ds:shrink-0\"\n onClick={() => {\n if (!waiting) state.send();\n }}\n >\n {sending\n ? t('registrationForm.verification.sendingCode')\n : waiting\n ? t('registrationForm.verification.resendIn', {\n seconds: state.cooldown,\n })\n : t('registrationForm.verification.sendCode')}\n </Button>\n );\n}\n\ninterface VerificationPanelProps {\n field: RegistrationVerifiableField;\n state: UseContactVerificationReturn;\n /** Hide \"Change email\": the address cannot be edited here. */\n canChange?: boolean;\n /** Show \"Change\" beside the success line of a field that started\n * verified (`allowChange`). The email shows it elsewhere. */\n changeWhenVerified?: boolean;\n /** Called after \"Change\" unlocks the field, to focus it. */\n onUnlocked?: () => void;\n /** Called once when the code is right, to put focus back on the field. */\n onVerified: () => void;\n}\n\n/** What sits under the field: the code box, or the success line. */\nexport function VerificationPanel({\n field,\n state,\n canChange = true,\n changeWhenVerified = false,\n onUnlocked,\n onVerified,\n}: VerificationPanelProps) {\n const { t } = useTranslation('ui');\n const panel = useRef<HTMLDivElement>(null);\n const message = useFailureMessage(state.failure);\n const open = state.status === 'sent' || state.status === 'verifying';\n const verifying = state.status === 'verifying';\n const complete = state.code.length === state.codeLength;\n\n const focusFirstBox = () =>\n panel.current?.querySelector<HTMLInputElement>('input')?.focus();\n\n // Focus follows the step: the code box when a code goes out and when a\n // check fails; the field itself when the code is right.\n const previous = useRef(state.status);\n const lastFailure = useRef(state.failure);\n useEffect(() => {\n const before = previous.current;\n previous.current = state.status;\n if (state.status === 'sent' && before === 'sending') focusFirstBox();\n if (state.status === 'sent' && before === 'verifying' && state.failure) {\n focusFirstBox();\n }\n if (state.status === 'verified' && before === 'verifying') onVerified();\n // eslint-disable-next-line react-hooks/exhaustive-deps -- only on a status change\n }, [state.status]);\n useEffect(() => {\n // A new failure while the box is open (a second wrong code).\n if (\n state.failure &&\n state.failure !== lastFailure.current &&\n state.status === 'sent'\n ) {\n focusFirstBox();\n }\n lastFailure.current = state.failure;\n }, [state.failure, state.status]);\n\n // The wait is shown in the button every second; a screen reader hears\n // it only when it starts and when it ends.\n const [announcement, setAnnouncement] = useState('');\n const waiting = state.cooldown > 0;\n const wasWaiting = useRef(false);\n useEffect(() => {\n if (waiting && !wasWaiting.current) {\n setAnnouncement(\n t('registrationForm.verification.resendIn', {\n seconds: state.cooldown,\n }),\n );\n } else if (!waiting && wasWaiting.current) {\n setAnnouncement(t('registrationForm.verification.resendCode'));\n }\n wasWaiting.current = waiting;\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the start value only\n }, [waiting, t]);\n\n const isEmail = field === 'email';\n const sentText = isEmail\n ? t('registrationForm.verification.codeSentEmail', {\n value: state.sentTo,\n })\n : t('registrationForm.verification.codeSentPhone', {\n value: state.sentTo,\n });\n const changeText = isEmail\n ? t('registrationForm.verification.changeEmail')\n : t('registrationForm.verification.changePhone');\n const verifiedText = isEmail\n ? t('registrationForm.verification.verifiedEmail')\n : t('registrationForm.verification.verifiedPhone');\n\n return (\n <div\n ref={panel}\n data-slot=\"verification\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\"\n >\n {/* Always mounted: a live region announces a change, not its first\n content. Holds the success line and the wait announcements. */}\n <div role=\"status\" className={state.verified ? undefined : 'ds:sr-only'}>\n {state.verified ? (\n <p className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-body-sm ds:text-success\">\n <CircleCheck aria-hidden=\"true\" className=\"ds:size-4 ds:shrink-0\" />\n <span>{verifiedText}</span>\n </p>\n ) : (\n announcement\n )}\n </div>\n\n {changeWhenVerified && state.changeable && (\n <Button\n type=\"button\"\n intent=\"secondary\"\n startIcon={<Pencil aria-hidden=\"true\" />}\n data-action=\"change-value\"\n className=\"ds:self-start\"\n onClick={() => {\n state.unlock();\n onUnlocked?.();\n }}\n >\n {changeText}\n </Button>\n )}\n\n {open && (\n <>\n <p className=\"type-body-sm ds:text-[var(--muted-foreground)]\">\n {sentText}\n </p>\n {state.devCode && (\n <Alert variant=\"info\" announce=\"off\">\n <Alert.Description>\n {t('registrationForm.verification.devCode', {\n code: state.devCode,\n })}\n </Alert.Description>\n </Alert>\n )}\n {/* A field of its own, so the code box has a label and its\n own message slot. */}\n <FormField\n label={t('registrationForm.verification.codeLabel')}\n error={message}\n >\n <OTPInput\n length={state.codeLength}\n mode=\"numeric\"\n webOtp={field === 'phone'}\n value={state.code}\n onChange={state.setCode}\n onComplete={(code) => state.verify(code)}\n disabled={verifying}\n />\n </FormField>\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-sm)]\">\n <Button\n type=\"button\"\n intent=\"primary\"\n size=\"md\"\n loading={verifying}\n aria-disabled={!complete || undefined}\n data-action=\"verify-code\"\n onClick={() => {\n if (complete) state.verify();\n }}\n >\n {verifying\n ? t('registrationForm.verification.verifying')\n : t('registrationForm.verification.verify')}\n </Button>\n <Button\n type=\"button\"\n intent=\"outline\"\n size=\"md\"\n disabled={verifying}\n aria-disabled={waiting || undefined}\n data-action=\"resend-code\"\n onClick={() => {\n if (!waiting) state.send();\n }}\n >\n {waiting\n ? t('registrationForm.verification.resendIn', {\n seconds: state.cooldown,\n })\n : t('registrationForm.verification.resendCode')}\n </Button>\n {canChange && (\n <Button\n type=\"button\"\n intent=\"link\"\n size=\"md\"\n disabled={verifying}\n data-action=\"change-value\"\n onClick={state.reset}\n >\n {changeText}\n </Button>\n )}\n </div>\n </>\n )}\n </div>\n );\n}\n\ninterface ChangeSlotProps {\n field: RegistrationVerifiableField;\n state: UseContactVerificationReturn;\n /** Called after the field is unlocked, to focus it. */\n onUnlocked: () => void;\n}\n\n/**\n * \"Change email\", in the cell where Confirm email sits. A hidden label\n * line above it keeps the action level with the input beside it.\n */\nexport function VerificationChangeSlot({\n field,\n state,\n onUnlocked,\n}: ChangeSlotProps) {\n const { t } = useTranslation('ui');\n return (\n <div\n data-slot=\"change-slot\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n {/* Only beside the email; stacked, it would leave a gap. */}\n <span\n aria-hidden=\"true\"\n className=\"type-label ds:invisible ds:hidden ds:@[544px]/registration:block\"\n >\n {'\\u00A0'}\n </span>\n <Button\n type=\"button\"\n intent=\"secondary\"\n startIcon={<Pencil aria-hidden=\"true\" />}\n data-action=\"change-value\"\n className=\"ds:self-start\"\n onClick={() => {\n state.unlock();\n onUnlocked();\n }}\n >\n {field === 'email'\n ? t('registrationForm.verification.changeEmail')\n : t('registrationForm.verification.changePhone')}\n </Button>\n </div>\n );\n}\n","/* -------------------------------------------------------------------- */\n/* RegistrationForm — the registration form card, for doctors and for */\n/* patients. */\n/* */\n/* One export for the card: name, email and password (each with a */\n/* confirm field), phone, speciality, terms and the submit button. The */\n/* host picks the fields: a doctor form shows them all, a patient form */\n/* shows email, password and terms. The host keeps the page around the */\n/* card, the marketing copy and every server rule. The card checks what */\n/* a browser can check and either hands the values to `onSubmit` or */\n/* posts a real form to the host's own field names. */\n/* */\n/* What happens on submit (the busy guard, the reCAPTCHA wait, telling */\n/* a server answer from a re-render) lives in `useRegistrationSubmit`. */\n/* -------------------------------------------------------------------- */\n\nimport {\n Fragment,\n forwardRef,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { Trans, useTranslation } from 'react-i18next';\nimport { cva } from 'class-variance-authority';\nimport { Check, CircleAlert } from 'lucide-react';\n// The same parser PhoneInput uses, for a number that arrives filled in.\nimport { parsePhoneNumberFromString } from 'libphonenumber-js/min';\n// The validator EmailInput itself uses, so the two never disagree.\nimport isEmail from 'validator/lib/isEmail';\nimport { Alert } from '../../components/alert';\nimport { Button } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { Checkbox } from '../../components/checkbox';\nimport { DevBypassButton } from '../../components/dev-bypass-button';\nimport { EmailInput } from '../../components/email-input';\nimport { ErrorSummary } from '../../components/error-summary';\nimport { FormField } from '../../components/form-field';\nimport { List } from '../../components/list';\nimport {\n PasswordInput,\n usePasswordRequirements,\n type UsePasswordRequirementsOptions,\n} from '../../components/password-input';\nimport { PhoneInput } from '../../components/phone-input';\nimport { RecaptchaWidget } from '../../components/recaptcha-widget';\nimport { Select, type SelectOption } from '../../components/select';\nimport { StateBackedTextInput } from '../../components/_shared/state-backed-text-input';\nimport { isDevelopment } from '../../components/_shared/is-development';\nimport { useStateBackedInput } from '../../components/_shared/use-state-backed-input';\nimport { isSafeHref, isSameSiteHref } from '../../components/_shared/safe-href';\nimport { useFieldMatch } from '../../hooks/use-field-match';\nimport { BrandMark, type BrandMarkMotion } from '../_shared/brand-mark';\nimport {\n useErrorSummary,\n useFormMessageAnnounce,\n} from '../_shared/use-error-summary';\nimport { useRegistrationSubmit } from './use-registration-submit';\nimport {\n useContactVerification,\n type RegistrationFieldVerification,\n type RegistrationVerifiableField,\n} from './use-contact-verification';\nimport {\n VerificationAction,\n VerificationChangeSlot,\n VerificationPanel,\n useSendFailureMessage,\n} from './registration-verification';\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** The fields of the form, in the order they appear. */\nexport const REGISTRATION_FORM_FIELDS = [\n 'firstName',\n 'lastName',\n 'email',\n 'emailConfirm',\n 'password',\n 'passwordConfirm',\n 'phone',\n 'branch',\n 'terms',\n] as const;\n\nexport type RegistrationFormField = (typeof REGISTRATION_FORM_FIELDS)[number];\n\n/** The fields built on `TextInput`, which can refuse paste or copy. */\nexport type RegistrationFormTextField = Extract<\n RegistrationFormField,\n | 'firstName'\n | 'lastName'\n | 'email'\n | 'emailConfirm'\n | 'password'\n | 'passwordConfirm'\n>;\n\n/** What `onSubmit` receives once every check has passed. A field the\n * form does not show is empty (`''`, or `false` for the terms). */\nexport interface RegistrationFormValues {\n firstName: string;\n lastName: string;\n email: string;\n /** As typed. It matches `email` apart from case and outer spaces. */\n emailConfirm: string;\n password: string;\n /** Equal to `password` when the confirm field is shown. */\n passwordConfirm: string;\n /** In E.164 form, e.g. `+393331234567`. */\n phone: string;\n /** The chosen `branches` value. */\n branch: string;\n /** True when the terms are shown: the form does not submit without. */\n terms: boolean;\n /** The reCAPTCHA token, when the host passes `recaptchaSiteKey`. */\n captchaToken?: string;\n}\n\n/** Values to show when the form opens. There is no password here, on\n * purpose: a password is never sent back to the browser. */\nexport type RegistrationFormInitialValues = Partial<\n Pick<\n RegistrationFormValues,\n | 'firstName'\n | 'lastName'\n | 'email'\n | 'emailConfirm'\n | 'phone'\n | 'branch'\n | 'terms'\n >\n>;\n\n/**\n * What the development shortcut puts in the fields. Unlike\n * `initialValues` it may carry a password: the host passes it only in\n * development, from its own server, and the kit holds no test data of\n * its own.\n */\nexport type RegistrationFormDevValues = Partial<\n Pick<\n RegistrationFormValues,\n | 'firstName'\n | 'lastName'\n | 'email'\n | 'password'\n | 'phone'\n | 'branch'\n | 'terms'\n >\n>;\n\n/** The development-only shortcut at the top right of the card. */\nexport interface RegistrationFormDevBypass {\n /** What the shortcut does: the button's name and tooltip. */\n label: string;\n /**\n * The values to put in the fields when the button is pressed, as if\n * typed: the checks, the password checklist and the posted values all\n * see them. The confirm fields are filled from the same values, so\n * they match. A field the form does not show is ignored, and a\n * read-only email is kept.\n */\n values?: RegistrationFormDevValues;\n /**\n * True to submit the form right after filling it, through the normal\n * path: the checks still run, reCAPTCHA still runs, a native form\n * still posts. Default false: fill only.\n */\n submit?: boolean;\n /** Called after filling, for a host with a route of its own. */\n onClick?: () => void;\n}\n\n/** Messages from the server, already translated by the host: one per\n * field, plus `form` for a message about the whole form. */\nexport type RegistrationFormErrors = Partial<\n Record<RegistrationFormField | 'form', string>\n>;\n\n/** The host's own form field names, for a native form post. `captcha`\n * names the hidden field that carries the reCAPTCHA token. */\nexport type RegistrationFormFieldNames = Partial<\n Record<RegistrationFormField | 'captcha', string>\n>;\n\nexport interface RegistrationFormProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'title' | 'onSubmit'\n> {\n /** Replaces the heading \"Create your account\". Pass it translated. */\n title?: string;\n /** A line under the heading, e.g. \"No installation needed\". Pass it\n * translated. */\n description?: string;\n /** The heading's level. Default 2, for a page that has its own `h1`. */\n headingLevel?: 1 | 2 | 3;\n /**\n * Shows the Alfadocs mark above the heading, with the heading and its\n * line centred under it. Default true. With `false` the heading sits\n * at the start edge, for a host that shows its own logo beside the\n * card.\n */\n showLogo?: boolean;\n /**\n * How the mark arrives when the card opens: its pieces come together\n * (`assemble`, the default), it turns once (`spin`), it beats\n * (`pulse`), or it is still (`none`). It plays once and rests, and\n * holds still under reduced motion and in the accessible themes.\n */\n logoMotion?: BrandMarkMotion;\n /**\n * Host content between the heading and the fields, such as a notice\n * or a list of benefits. It sits outside the form, so nothing in it is\n * posted. Keep any heading inside it below the card's own level.\n */\n children?: ReactNode;\n /**\n * A short notice above the fields, as plain text already translated. It\n * shows as an info alert, quiet to screen readers (it is not news). For\n * a server-rendered page that can only pass JSON. Comes before\n * `benefits` and `children`.\n */\n notice?: string;\n /**\n * What the person gets, one short line each, already translated. They\n * show as a compact list with a tick. Comes after `notice` and before\n * `children`.\n */\n benefits?: string[];\n /**\n * The fields to show. Default: all of them, which is the doctor form.\n * A patient form is `['email', 'password', 'passwordConfirm', 'terms']`.\n * Leave out `emailConfirm` or `passwordConfirm` to drop that confirm\n * field. The list picks fields, it does not order them; email and\n * password always show; `branch` also needs `branches`.\n */\n fields?: readonly RegistrationFormField[];\n /** Values to show when the form opens, such as the email from an\n * invite link. Read once. Never a password. */\n initialValues?: RegistrationFormInitialValues;\n /**\n * Messages from the server, already translated. Each shows on its\n * field until the user changes that field; `form` shows above the\n * fields, as does a message for a field the form does not show.\n *\n * Messages present when the form opens (a page the server rendered\n * after a failed post) take focus: the error summary at the top of the\n * form, which lists each field with a message, or the message above the\n * fields when no field has one.\n *\n * On a React host, when the messages change, both password fields\n * are emptied and focus moves as above. Set `submitting` while you\n * send: the form then also notices an answer that says the same as\n * the last one (another address, also taken), which the messages\n * alone cannot show. Any object works, kept in state or rebuilt on\n * each render (`errors={{ email: emailError }}`).\n */\n errors?: RegistrationFormErrors;\n /**\n * Shows the email from `initialValues` read-only, for a person invited\n * with an address they cannot change here. Off by default: choose it\n * only when the server will refuse any other address. The value is\n * still posted and still read out, there is no confirm email field,\n * and the browser does not check it. Ignored when there is no initial\n * email, so the field is never both empty and locked.\n */\n emailReadOnly?: boolean;\n /** A line under the email field, e.g. \"You can change it later in the\n * settings\". Pass it translated. */\n emailDescription?: string;\n /**\n * Fields that refuse paste and drop, so the user types them, e.g.\n * `['passwordConfirm']`. Default: none. Autofill from the browser or a\n * password manager still works. A refused paste is announced and shown\n * under the field. The host decides: see the docs for the WCAG\n * position, which differs between the email and password fields.\n */\n blockPaste?: readonly RegistrationFormTextField[];\n /**\n * Fields that refuse copy, cut and dragging text out. Default: none.\n * Browsers already refuse to copy from a password field while it is\n * hidden. See the docs for the WCAG position.\n */\n blockCopy?: readonly RegistrationFormTextField[];\n /** The specialities to choose from. The field shows, and is required,\n * only when this has entries. */\n branches?: SelectOption[];\n /**\n * The password rules, shown as a live checklist. Keep them equal to\n * the server's. Default: 12 characters with an uppercase letter, a\n * lowercase letter and a number, counting only `A-Z`, `a-z` and `0-9`\n * (`charset: 'ascii'`), which is the platform's rule.\n */\n passwordPolicy?: UsePasswordRequirementsOptions;\n /**\n * Where \"terms of use\" leads. A path on the same site, or an address\n * written in full (`https://…`). Anything else, such as an address\n * that would lead off the site without saying so, shows the words\n * without a link.\n */\n termsHref?: string;\n /** Where \"privacy policy\" leads. Same rule as `termsHref`. */\n privacyHref?: string;\n /**\n * Replaces the sentence beside the terms box (\"I accept the terms of\n * use and the privacy policy\") with the host's own wording and links,\n * already translated. The legal wording is the host's to choose. When\n * set, `termsHref` and `privacyHref` are not used. The box stays\n * required.\n */\n termsLabel?: ReactNode;\n /**\n * `termsLabel` as a string, for a host that can only pass JSON. Already\n * translated. Mark the links with `<terms>…</terms>` and\n * `<privacy>…</privacy>`: they lead to `termsHref` and `privacyHref`\n * (new tab; without a safe address, the words show without a link).\n * Any other tag shows its text only. No marker: plain text. Ignored\n * when `termsLabel` is set.\n */\n termsLabelText?: string;\n /** A line shown with the terms box and read out with it, e.g. \"We\n * will not send you any advertising\". Pass it translated. */\n termsDescription?: ReactNode;\n /** `termsDescription` as a string, with the same markers as\n * `termsLabelText`. Ignored when `termsDescription` is set. */\n termsDescriptionText?: string;\n /** Adds \"Already have an account? Sign in\". Same rule as `termsHref`. */\n loginHref?: string;\n /** A Google reCAPTCHA v2 site key of the invisible type. The check\n * runs when the user submits. Leave it out where the server does not\n * verify a token. */\n recaptchaSiteKey?: string;\n /** Replaces the button's \"Create account\". Pass it translated. */\n submitLabel?: string;\n /** True while the host sends the values: the button shows a spinner\n * and a second submit is ignored. */\n submitting?: boolean;\n /**\n * Shows the development-only shortcut button at the top right of the\n * card: it fills the form with the host's `values`, and submits it\n * when asked to. Pass it only when the server says this is a\n * development environment: the kit never decides that itself, holds\n * no test data, and what the shortcut submits goes through the normal\n * path, so the server's own rules still decide. With neither `values`\n * nor `onClick` there is nothing to do and no button.\n */\n devBypass?: RegistrationFormDevBypass;\n /** For React hosts: called with the values once every check has\n * passed. Not called when `fieldNames` is set. */\n onSubmit?: (values: RegistrationFormValues) => void;\n /**\n * For a native form post: the host's own field names, e.g.\n * `{ email: 'registration[email]' }`. When set, the inputs carry\n * these names and the browser posts the form. A field without a name\n * here is not posted: name a confirm field only if the server's form\n * has one, or it may refuse the post as carrying extra fields.\n */\n fieldNames?: RegistrationFormFieldNames;\n /**\n * Where a native form post goes. Default: the current address, query\n * string included, which is what a page reached through an invite link\n * needs. Only an address on this site is accepted: another site is\n * never sent what the user typed, and the post then goes to the\n * current address instead.\n */\n action?: string;\n /**\n * Extra hidden inputs posted with a native form, by name: a CSRF token\n * or similar. Not used with `onSubmit`. A name that is also one of\n * `fieldNames` is left out: the form's own field wins.\n */\n hiddenFields?: Readonly<Record<string, string>>;\n /**\n * Proves an email or a phone number with a code before the form\n * submits. For each field named here the card shows \"Send code\" beside\n * the field, a code box once a code is out, and locks the field\n * (read-only, still posted) when the code is right. The host sends and\n * checks the codes on its server, which must also refuse the form when\n * the value was not verified: this is a convenience for the person,\n * not the check. Without it the form is unchanged.\n *\n * `Confirm email` stays; leave `emailConfirm` out of `fields` to drop it.\n */\n verification?: Partial<\n Record<RegistrationVerifiableField, RegistrationFieldVerification>\n >;\n /**\n * With `verification`, the form does not submit until every field named\n * there is verified. Default true.\n */\n requireVerification?: boolean;\n}\n\n/* -------------------------------------------------------------------- */\n/* Styles */\n/* -------------------------------------------------------------------- */\n\nconst registrationFormVariants = cva(\n 'ds:@container/registration ds:w-full ds:text-start ds:text-[var(--foreground)]',\n);\n\nconst rowVariants = cva(\n 'ds:grid ds:grid-cols-1 ds:items-start ds:gap-[var(--spacing-md)]',\n {\n variants: {\n columns: {\n /** A field alone in its row takes the full width. */\n one: '',\n /** Two fields side by side once the card is wide enough. */\n two: 'ds:@[544px]/registration:grid-cols-2',\n },\n },\n defaultVariants: { columns: 'two' },\n },\n);\n\n/** The top of the card: the mark, the heading and its line. */\nconst headerVariants = cva('ds:relative ds:flex ds:gap-[var(--spacing-sm)]', {\n variants: {\n logo: {\n /** A centred column under the mark. */\n true: 'ds:flex-col ds:items-center',\n /** The heading at the start edge, the shortcut at the end. */\n false: 'ds:items-start ds:justify-between',\n },\n },\n defaultVariants: { logo: true },\n});\n\nconst headingBlockVariants = cva(\n 'ds:flex ds:min-w-0 ds:flex-col ds:gap-[var(--spacing-xs)]',\n {\n variants: {\n centred: { true: 'ds:items-center ds:text-center', false: '' },\n },\n defaultVariants: { centred: true },\n },\n);\n\n/** Where the development shortcut sits: the top inline-end corner. Out\n * of the flow under the mark, so it cannot push the mark off centre. */\nconst shortcutVariants = cva('ds:shrink-0', {\n variants: {\n corner: { true: 'ds:absolute ds:top-0 ds:end-0', false: '' },\n },\n defaultVariants: { corner: true },\n});\n\n// Links inside the card take the text colour and an underline. The kit\n// Link's own colour (`--primary`) falls just below AA on a card in the\n// dark theme, as the booking form's consent links found.\nconst inlineLinkVariants = cva(\n 'ds:rounded-[var(--radius-sm)] ds:underline ds:underline-offset-4 ds:text-[var(--foreground)] ds:focus-visible:outline-solid ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n {\n variants: {\n weight: { normal: '', strong: 'ds:font-semibold' },\n },\n defaultVariants: { weight: 'normal' },\n },\n);\n\n// The message above the fields takes focus when there is no field to\n// send the user to, so it shows a ring like anything else that does.\nconst formMessageVariants = cva(\n 'ds:focus-visible:outline-solid ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n);\n\n/** The `*` beside a required field, as FormField draws it. Decorative:\n * the control itself says it is required. */\nconst requiredMarkVariants = cva(\n 'ds:text-destructive ds:ms-[var(--spacing-xs)]',\n);\n\n/* -------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------- */\n\n// The platform's rule is written in ASCII (`[A-Z]`, `[a-z]`, `\\d`), so\n// the checklist counts the same characters and never shows green for a\n// password the server will refuse.\nconst DEFAULT_PASSWORD_POLICY: UsePasswordRequirementsOptions = {\n minLength: 12,\n uppercase: true,\n lowercase: true,\n digit: true,\n charset: 'ascii',\n};\n\n// A brand name, not interface copy: it reads the same in every language,\n// so it has no translation key.\nconst BRAND_NAME = 'Alfadocs';\n\n/** A <terms> or <privacy> span in a host sentence. */\nconst MARKED = /<(terms|privacy)>([\\s\\S]*?)<\\/\\1>/;\n/** Any other tag: its text stays, the tag goes. */\nconst OTHER_TAGS = /<\\/?(?!(?:terms|privacy)\\b)[a-z][^>]*>/gi;\n\n/** An address a link may use, or nothing. */\nconst linkTo = (href: string | undefined): string | undefined =>\n href && isSafeHref(href) ? href : undefined;\n\nconst hasMessage = (errors: RegistrationFormErrors): boolean =>\n Object.values(errors).some(Boolean);\n\n/** Whether a number could be a real one, by its length for its country. */\nconst isPossiblePhone = (e164: string): boolean =>\n parsePhoneNumberFromString(e164)?.isPossible() ?? false;\n\ninterface InlineLinkProps {\n href: string;\n /** Opens in a new tab, so the form keeps what the user has typed. */\n newTab?: boolean;\n weight?: 'normal' | 'strong';\n /** Emitted as `data-action`. */\n action?: string;\n /** The link's text: `Trans` fills it in from the translation. */\n children?: ReactNode;\n}\n\n// `Trans` hands every element it fills a bookkeeping prop of its own, so\n// these two take named props only and pass nothing else on to the DOM.\n\n/** A link inside a sentence. */\nfunction InlineLink({\n href,\n newTab = false,\n weight,\n action,\n children,\n}: InlineLinkProps) {\n const { t } = useTranslation('ui');\n return (\n <a\n href={href}\n target={newTab ? '_blank' : undefined}\n rel={newTab ? 'noopener noreferrer' : undefined}\n data-action={action}\n className={inlineLinkVariants({ weight })}\n >\n {children}\n {newTab && <span className=\"ds:sr-only\">{t('link.opensInNewTab')}</span>}\n </a>\n );\n}\n\n/** The words a link would wrap, when the host gives no address for it. */\nfunction PlainText({ children }: { children?: ReactNode }) {\n return <>{children}</>;\n}\n\n/** What a field's wrapper reports as `data-verification`. */\nfunction verificationStep(\n state: ReturnType<typeof useContactVerification>,\n): 'idle' | 'sent' | 'verified' | undefined {\n if (!state.enabled) return undefined;\n if (state.verified) return 'verified';\n return state.status === 'sent' || state.status === 'verifying'\n ? 'sent'\n : 'idle';\n}\n\ntype FieldFlags = Partial<Record<RegistrationFormField, boolean>>;\n\n/** Where focus can be sent: a field, or the message above the fields. */\ntype FocusTarget = RegistrationFormField | 'form';\n\n/** Every field but the terms, which is a checkbox under the grid. */\ntype GridField = Exclude<RegistrationFormField, 'terms'>;\n\n/** A field sits beside the one it belongs with. */\nconst FIELD_PAIRS: ReadonlyArray<readonly [GridField, GridField]> = [\n ['firstName', 'lastName'],\n ['email', 'emailConfirm'],\n ['password', 'passwordConfirm'],\n ['phone', 'branch'],\n];\n\n/** The rows of the form, for the fields that show. A pair keeps its\n * row; two fields left alone one after the other share a row, so a\n * form of just email and password puts them side by side. */\nfunction layOutRows(shows: (field: GridField) => boolean): GridField[][] {\n const rows: GridField[][] = [];\n for (const pair of FIELD_PAIRS) {\n const row = pair.filter(shows);\n if (row.length === 0) continue;\n const last = rows[rows.length - 1];\n if (row.length === 1 && last?.length === 1) last.push(row[0]);\n else rows.push(row);\n }\n return rows;\n}\n\ninterface FormState {\n firstName: string;\n lastName: string;\n email: string;\n emailConfirm: string;\n password: string;\n passwordConfirm: string;\n phone: string;\n branch: string;\n terms: boolean;\n}\n\n/* -------------------------------------------------------------------- */\n/* RegistrationForm */\n/* -------------------------------------------------------------------- */\n\n/**\n * The registration form card, for doctors and for patients. The host\n * picks the fields, supplies the page around the card and owns every\n * server rule; see the props for the two ways to submit. The card's\n * text follows the kit's language, like every kit component.\n */\nexport const RegistrationForm = forwardRef<\n HTMLDivElement,\n RegistrationFormProps\n>(\n (\n {\n title,\n description,\n headingLevel = 2,\n showLogo = true,\n logoMotion = 'assemble',\n children,\n fields,\n initialValues,\n errors,\n emailReadOnly = false,\n emailDescription,\n blockPaste,\n blockCopy,\n branches,\n passwordPolicy = DEFAULT_PASSWORD_POLICY,\n termsHref,\n privacyHref,\n termsLabel: termsLabelNode,\n termsDescription: termsDescriptionNode,\n termsLabelText,\n termsDescriptionText,\n notice,\n benefits,\n loginHref,\n recaptchaSiteKey,\n submitLabel,\n submitting = false,\n devBypass,\n onSubmit,\n fieldNames,\n action,\n hiddenFields,\n verification,\n requireVerification = true,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const titleId = useId();\n const fieldIdBase = useId();\n /** The id of a field's wrapper: where the summary's link leads. */\n const fieldId = (field: RegistrationFormField) => `${fieldIdBase}-${field}`;\n const termsErrorId = useId();\n const termsDescriptionId = useId();\n const formMessageId = useId();\n const native = fieldNames !== undefined;\n const hasBranches = Boolean(branches && branches.length > 0);\n // Locked only when there is an address to lock: an empty read-only\n // field would leave the user with no way forward.\n const [hadEmail] = useState(() => Boolean(initialValues?.email));\n const emailLocked = emailReadOnly && hadEmail;\n\n /** Whether the form shows a field. */\n const shows = (field: RegistrationFormField): boolean => {\n if (field === 'email' || field === 'password') return true;\n if (fields && !fields.includes(field)) return false;\n if (field === 'branch') return hasBranches;\n // Nothing to mistype in an address the user cannot type.\n // Not while the code proves the address: nothing to retype.\n if (field === 'emailConfirm') return !emailLocked && !emailVerified;\n return true;\n };\n\n /* ------------------------------ State ----------------------------- */\n\n // Read once. Passwords always start empty.\n const [values, setValues] = useState<FormState>(() => ({\n firstName: initialValues?.firstName ?? '',\n lastName: initialValues?.lastName ?? '',\n email: initialValues?.email ?? '',\n emailConfirm: initialValues?.emailConfirm ?? '',\n password: '',\n passwordConfirm: '',\n phone: initialValues?.phone ?? '',\n branch: initialValues?.branch ?? '',\n terms: initialValues?.terms ?? false,\n }));\n // PhoneInput says whether a number is possible each time it changes.\n const [phonePossible, setPhonePossible] = useState(() =>\n isPossiblePhone(initialValues?.phone ?? ''),\n );\n // A field the user has left. An email that arrives filled in counts,\n // as it does inside EmailInput: both then flag a bad one at once, so\n // the field is never red without a message.\n const [touched, setTouched] = useState<FieldFlags>(() => ({\n email: Boolean(initialValues?.email),\n }));\n const [submitted, setSubmitted] = useState(false);\n const [serverErrors, setServerErrors] = useState<RegistrationFormErrors>(\n () => errors ?? {},\n );\n\n /* --------------------------- Verification ------------------------- */\n\n const emailVerification = useContactVerification({\n config: verification?.email,\n value: values.email,\n });\n const phoneVerification = useContactVerification({\n config: shows('phone') ? verification?.phone : undefined,\n value: values.phone,\n });\n const emailVerified = emailVerification.verified;\n const phoneVerified = phoneVerification.verified;\n const shown = REGISTRATION_FORM_FIELDS.filter(shows);\n // Where \"Change email\" sits: the Confirm email cell.\n const changeSlot =\n !emailLocked && emailVerified && emailVerification.changeable;\n /** A field the person still has to prove. */\n const emailNeedsCode =\n requireVerification && emailVerification.enabled && !emailVerified;\n const phoneNeedsCode =\n requireVerification && phoneVerification.enabled && !phoneVerified;\n const emailSendFailure = useSendFailureMessage(emailVerification);\n const phoneSendFailure = useSendFailureMessage(phoneVerification);\n\n const set = <K extends keyof FormState>(field: K, value: FormState[K]) => {\n setValues((previous) => ({ ...previous, [field]: value }));\n // The server's message was about the old value.\n setServerErrors((previous) =>\n previous[field] ? { ...previous, [field]: undefined } : previous,\n );\n };\n const leave = (field: RegistrationFormField) =>\n setTouched((previous) =>\n previous[field] ? previous : { ...previous, [field]: true },\n );\n const emptyPasswords = () => {\n setValues((previous) => ({\n ...previous,\n password: '',\n passwordConfirm: '',\n }));\n setTouched((previous) => ({\n ...previous,\n password: false,\n passwordConfirm: false,\n }));\n };\n\n /** The paste and copy switches for one typed field. */\n const clipboard = (field: RegistrationFormTextField) => ({\n blockPaste: blockPaste?.includes(field) ?? false,\n blockCopy: blockCopy?.includes(field) ?? false,\n });\n\n /* ---------------------------- Validation -------------------------- */\n\n const requirements = usePasswordRequirements(passwordPolicy);\n const emailMatch = useFieldMatch({\n value: values.email,\n confirmValue: values.emailConfirm,\n kind: 'email',\n submitted,\n });\n const passwordMatch = useFieldMatch({\n value: values.password,\n confirmValue: values.passwordConfirm,\n kind: 'password',\n submitted,\n });\n\n /** What stops a submit, whether or not the message shows yet. Only\n * a field that shows can stop it. */\n const invalid: Record<RegistrationFormField, boolean> = {\n firstName: shows('firstName') && values.firstName.trim() === '',\n lastName: shows('lastName') && values.lastName.trim() === '',\n // The user cannot fix a locked address, so the server judges it.\n email: (!emailLocked && !isEmail(values.email)) || emailNeedsCode,\n emailConfirm:\n shows('emailConfirm') &&\n (values.emailConfirm === '' || !emailMatch.matches),\n password:\n values.password === '' ||\n !requirements.every((rule) => rule.test(values.password)),\n passwordConfirm:\n shows('passwordConfirm') &&\n (values.passwordConfirm === '' || !passwordMatch.matches),\n phone:\n shows('phone') &&\n (values.phone === '' || !phonePossible || phoneNeedsCode),\n branch: shows('branch') && values.branch === '',\n terms: shows('terms') && !values.terms,\n };\n\n // A message shows once the user has left the field or tried to\n // submit. The terms box waits for a submit: leaving it to follow one\n // of its own links is not a mistake.\n const due = (field: RegistrationFormField) =>\n submitted || (field !== 'terms' && touched[field] === true);\n const required = t('registrationForm.required');\n /** Each grid field's label: on the field, and in the summary. */\n const labels: Record<GridField, string> = {\n firstName: t('registrationForm.firstName'),\n lastName: t('registrationForm.lastName'),\n email: t('registrationForm.email'),\n emailConfirm: t('registrationForm.emailConfirm'),\n password: t('registrationForm.password'),\n passwordConfirm: t('registrationForm.passwordConfirm'),\n phone: t('registrationForm.phone'),\n branch: t('registrationForm.branch'),\n };\n const whenDue = (field: RegistrationFormField, message: string) =>\n due(field) && invalid[field] ? message : undefined;\n\n const ownErrors: Record<RegistrationFormField, string | undefined> = {\n firstName: whenDue('firstName', required),\n lastName: whenDue('lastName', required),\n email:\n due('email') && !emailLocked && !isEmail(values.email)\n ? values.email === ''\n ? required\n : t('inputs.email.invalid')\n : submitted && emailNeedsCode\n ? t('registrationForm.verification.emailRequired')\n : undefined,\n emailConfirm:\n values.emailConfirm === ''\n ? whenDue('emailConfirm', required)\n : emailMatch.error,\n password: whenDue(\n 'password',\n values.password === ''\n ? required\n : t('registrationForm.passwordInvalid'),\n ),\n passwordConfirm:\n values.passwordConfirm === ''\n ? whenDue('passwordConfirm', required)\n : passwordMatch.error,\n phone:\n due('phone') &&\n shows('phone') &&\n (values.phone === '' || !phonePossible)\n ? values.phone === ''\n ? required\n : t('registrationForm.phoneInvalid')\n : submitted && phoneNeedsCode\n ? t('registrationForm.verification.phoneRequired')\n : undefined,\n branch: whenDue('branch', required),\n terms: whenDue('terms', t('registrationForm.termsRequired')),\n };\n const sendFailures: Partial<Record<RegistrationFormField, string>> = {\n email: emailSendFailure,\n phone: phoneSendFailure,\n };\n const errorFor = (field: RegistrationFormField) =>\n serverErrors[field] ?? sendFailures[field] ?? ownErrors[field];\n\n /* ------------------------------ Focus ----------------------------- */\n\n const controls = useRef<\n Partial<Record<RegistrationFormField, HTMLElement | null>>\n >({});\n const control = useMemo(() => {\n const bind =\n (field: RegistrationFormField) => (node: HTMLElement | null) => {\n controls.current[field] = node;\n };\n return {\n firstName: bind('firstName'),\n lastName: bind('lastName'),\n email: bind('email'),\n emailConfirm: bind('emailConfirm'),\n password: bind('password'),\n passwordConfirm: bind('passwordConfirm'),\n phone: bind('phone'),\n branch: bind('branch'),\n terms: bind('terms'),\n };\n }, []);\n // The addresses stay out of the inputs' `value` attributes, where a\n // copied outerHTML or a session replay could read them. The names do\n // too, through StateBackedTextInput.\n const emailField = useStateBackedInput(values.email, control.email);\n const emailConfirmField = useStateBackedInput(\n values.emailConfirm,\n control.emailConfirm,\n );\n const formMessage = useRef<HTMLDivElement>(null);\n\n /** Where to send the user for a set of server messages: the first\n * field on screen that has one, or the message above the fields\n * when only that says something. */\n const focusTargetFor = (\n messages: RegistrationFormErrors,\n ): FocusTarget | undefined =>\n shown.find((field) => messages[field]) ??\n (hasMessage(messages) ? 'form' : undefined);\n\n // Every field with a message after a refused submit, or after a server\n // answer, is listed at the top of the form, and focus goes there. A\n // page the server rendered after a failed post opens that way too: it\n // announces nothing itself.\n const [openedWithFieldMessage] = useState(() =>\n shown.some((field) => Boolean(errors?.[field])),\n );\n const summary = useErrorSummary(shown, errorFor, openedWithFieldMessage);\n\n // Any other place focus goes: the message above the fields, when no\n // field has one. A new object for each request, so asking twice for the\n // same place moves focus twice. The effect runs after the messages are\n // drawn, so a screen reader lands on something that already says what\n // is wrong.\n const [focusRequest, setFocusRequest] = useState<{\n target: FocusTarget;\n } | null>(() => {\n const target = openedWithFieldMessage\n ? undefined\n : focusTargetFor(errors ?? {});\n return target ? { target } : null;\n });\n useEffect(() => {\n if (!focusRequest) return;\n if (focusRequest.target === 'form') formMessage.current?.focus();\n else controls.current[focusRequest.target]?.focus();\n }, [focusRequest]);\n\n // PhoneInput has no blur event of its own, so listen on its input.\n const showsPhone = shows('phone');\n useEffect(() => {\n const input = controls.current.phone;\n if (!showsPhone || !input) return undefined;\n const onBlur = () =>\n setTouched((previous) =>\n previous.phone ? previous : { ...previous, phone: true },\n );\n input.addEventListener('blur', onBlur);\n return () => input.removeEventListener('blur', onBlur);\n }, [showsPhone]);\n\n /* ------------------------------ Submit ---------------------------- */\n\n const form = useRef<HTMLFormElement>(null);\n const captchaInput = useRef<HTMLInputElement>(null);\n\n /* --------------------- Development shortcut ----------------------- */\n\n // Asks for a submit once the filled values are on the page.\n const [submitRequest, setSubmitRequest] = useState<object | null>(null);\n useEffect(() => {\n if (submitRequest) form.current?.requestSubmit();\n }, [submitRequest]);\n\n const runDevBypass = () => {\n const filled = devBypass?.values;\n if (filled) {\n // Through the same state as the user's typing, and only into\n // fields that show. A locked email keeps its address.\n const email = emailLocked || emailVerified ? undefined : filled.email;\n const next: Partial<FormState> = {};\n if (shows('firstName') && filled.firstName !== undefined)\n next.firstName = filled.firstName;\n if (shows('lastName') && filled.lastName !== undefined)\n next.lastName = filled.lastName;\n if (email !== undefined) next.email = email;\n if (shows('emailConfirm') && email !== undefined)\n next.emailConfirm = email;\n if (filled.password !== undefined) next.password = filled.password;\n if (shows('passwordConfirm') && filled.password !== undefined)\n next.passwordConfirm = filled.password;\n if (shows('phone') && !phoneVerified && filled.phone !== undefined)\n next.phone = filled.phone;\n if (shows('branch') && filled.branch !== undefined)\n next.branch = filled.branch;\n if (shows('terms') && filled.terms !== undefined)\n next.terms = filled.terms;\n setValues((previous) => ({ ...previous, ...next }));\n if (next.phone !== undefined)\n setPhonePossible(isPossiblePhone(next.phone));\n // The server's messages were about the old values.\n setServerErrors((previous) => {\n const kept = { ...previous };\n for (const field of Object.keys(next) as (keyof FormState)[]) {\n kept[field] = undefined;\n }\n return kept;\n });\n if (devBypass.submit) setSubmitRequest({});\n }\n devBypass?.onClick?.();\n };\n\n const submit = useRegistrationSubmit<RegistrationFormField>({\n errors,\n submitting,\n native,\n captcha: Boolean(recaptchaSiteKey),\n firstProblem: () => shown.find((field) => invalid[field]),\n onRefused: (field) => {\n // Every message now shows, listed in the summary, which takes focus.\n setSubmitted(true);\n summary.open(() => setFocusRequest({ target: field }));\n },\n deliver: (captchaToken) => {\n if (native) {\n if (captchaInput.current && captchaToken) {\n captchaInput.current.value = captchaToken;\n }\n form.current?.submit();\n return;\n }\n // A field that does not show is empty, whatever it started with.\n const text = (field: GridField) => (shows(field) ? values[field] : '');\n onSubmit?.({\n firstName: text('firstName'),\n lastName: text('lastName'),\n email: values.email,\n emailConfirm: text('emailConfirm'),\n password: values.password,\n passwordConfirm: text('passwordConfirm'),\n phone: text('phone'),\n branch: text('branch'),\n terms: shows('terms') && values.terms,\n captchaToken,\n });\n },\n onAnswer: (answer) => {\n const next: RegistrationFormErrors = answer;\n setServerErrors(next);\n if (!hasMessage(next)) return;\n // Never keep a password the server did not accept.\n emptyPasswords();\n setSubmitted(false);\n // The summary when a field has a message, else the message above.\n summary.open(() => {\n const target = focusTargetFor(next);\n if (target) setFocusRequest({ target });\n });\n },\n // The page came back from the browser's cache as it was left:\n // the passwords must not come back with it.\n onRestore: emptyPasswords,\n });\n const { busy, captchaFailed } = submit;\n\n // A failed reCAPTCHA check has no field of its own: send the user to\n // the message above the fields, which may be off screen.\n useEffect(() => {\n if (captchaFailed) setFocusRequest({ target: 'form' });\n }, [captchaFailed]);\n\n /* ------------------------------ Render ---------------------------- */\n\n const name = (field: RegistrationFormField) =>\n native ? fieldNames[field] : field;\n const Heading = `h${headingLevel}` as const;\n const termsLink = linkTo(termsHref);\n const privacyLink = linkTo(privacyHref);\n const loginLink = linkTo(loginHref);\n // The host's own sentence as a string: <terms> and <privacy> become\n // links, any other tag shows its text, and no HTML is ever created.\n // Read here, not through i18n: the sentence is already translated.\n const marked = (text: string): ReactNode => {\n const parts = text.replace(OTHER_TAGS, '').split(MARKED);\n return parts.map((part, index) => {\n if (index % 3 !== 0) return null;\n const tag = parts[index + 1];\n const words = parts[index + 2];\n const href = tag === 'terms' ? termsLink : privacyLink;\n return (\n <Fragment key={index}>\n {part}\n {tag === undefined ? null : href ? (\n <InlineLink href={href} newTab>\n {words}\n </InlineLink>\n ) : (\n words\n )}\n </Fragment>\n );\n });\n };\n const termsLabel =\n termsLabelNode ?? (termsLabelText ? marked(termsLabelText) : undefined);\n const termsDescription =\n termsDescriptionNode ??\n (termsDescriptionText ? marked(termsDescriptionText) : undefined);\n const benefitLines = benefits?.filter(Boolean) ?? [];\n const hasHostContent =\n Boolean(notice) || benefitLines.length > 0 || Boolean(children);\n const formAction =\n native && action && isSameSiteHref(action) ? action : undefined;\n // What shows above the fields: the server's message about the whole\n // form, its message about any field that is not on screen (so nothing\n // it says is lost), and a failed reCAPTCHA check.\n const formError =\n [\n serverErrors.form,\n ...REGISTRATION_FORM_FIELDS.filter((field) => !shows(field)).map(\n (field) => serverErrors[field],\n ),\n captchaFailed ? t('inputs.recaptcha.error') : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n // Quiet while the summary lists a field: the summary reads it then.\n const formMessageAnnounce = useFormMessageAnnounce(\n formError,\n summary.listed.length > 0,\n );\n const termsError = errorFor('terms');\n const termsDescribedBy =\n [\n termsDescription ? termsDescriptionId : undefined,\n termsError ? termsErrorId : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n // The host's extra hidden inputs. The form's own fields keep their\n // names: an extra one that asks for the same name is left out.\n const ownNames = new Set(Object.values(fieldNames ?? {}));\n const extraFields = native ? Object.entries(hiddenFields ?? {}) : [];\n const clashes = extraFields\n .filter(([extraName]) => ownNames.has(extraName))\n .map(([extraName]) => extraName)\n .join(', ');\n useEffect(() => {\n if (clashes && isDevelopment()) {\n console.warn(\n `RegistrationForm: hiddenFields \"${clashes}\" is also named in fieldNames and was left out. The form's own field wins.`,\n );\n }\n }, [clashes]);\n\n // Read-only once the code is right, like a locked address.\n const emailReadOnlyNow = emailLocked || emailVerified;\n const emailInput = (\n <EmailInput\n ref={emailField.ref}\n name={name('email')}\n errorMessage={null}\n disableBuiltInValidation={emailReadOnlyNow}\n readOnly={emailReadOnlyNow}\n onChange={emailField.quiet((event) => set('email', event.target.value))}\n onBlur={() => leave('email')}\n {...clipboard('email')}\n />\n );\n const phoneInput = (\n <PhoneInput\n ref={control.phone}\n name={native ? undefined : 'phone'}\n value={values.phone}\n readOnly={phoneVerified}\n onChange={(e164, meta) => {\n set('phone', e164);\n setPhonePossible(meta.isPossible);\n }}\n />\n );\n\n const renderField = (field: GridField): ReactNode => {\n switch (field) {\n case 'firstName':\n return (\n <FormField\n key={field}\n id={fieldId(field)}\n label={labels.firstName}\n required\n error={errorFor('firstName')}\n announceError={!summary.lists('firstName')}\n data-field=\"firstName\"\n >\n <StateBackedTextInput\n ref={control.firstName}\n name={name('firstName')}\n autoComplete=\"given-name\"\n value={values.firstName}\n onChange={(event) => set('firstName', event.target.value)}\n onBlur={() => leave('firstName')}\n {...clipboard('firstName')}\n />\n </FormField>\n );\n case 'lastName':\n return (\n <FormField\n key={field}\n id={fieldId(field)}\n label={labels.lastName}\n required\n error={errorFor('lastName')}\n announceError={!summary.lists('lastName')}\n data-field=\"lastName\"\n >\n <StateBackedTextInput\n ref={control.lastName}\n name={name('lastName')}\n autoComplete=\"family-name\"\n value={values.lastName}\n onChange={(event) => set('lastName', event.target.value)}\n onBlur={() => leave('lastName')}\n {...clipboard('lastName')}\n />\n </FormField>\n );\n case 'email':\n return (\n <FormField\n key={field}\n id={fieldId(field)}\n label={labels.email}\n required={!emailLocked}\n description={emailDescription}\n error={errorFor('email')}\n announceError={!summary.lists('email')}\n data-field=\"email\"\n data-verification={verificationStep(emailVerification)}\n >\n {/* EmailInput still checks the format and marks the input.\n Its message goes through FormField, so there is one\n message, in one place. Read-only, not disabled: the\n address is still posted and still read out. */}\n {emailVerification.enabled ? (\n <div className=\"ds:@container/verify ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:flex-col ds:items-start ds:gap-[var(--spacing-sm)] ds:@[384px]/verify:flex-row\">\n <div className=\"ds:min-w-0 ds:w-full ds:@[384px]/verify:w-auto ds:@[384px]/verify:flex-1\">\n {emailInput}\n </div>\n <VerificationAction\n state={emailVerification}\n canSend={isEmail(values.email)}\n />\n </div>\n <VerificationPanel\n field=\"email\"\n state={emailVerification}\n canChange={!emailLocked}\n onVerified={() => controls.current.email?.focus()}\n />\n </div>\n ) : (\n emailInput\n )}\n </FormField>\n );\n case 'emailConfirm':\n if (changeSlot) {\n return (\n <VerificationChangeSlot\n key={field}\n field=\"email\"\n state={emailVerification}\n onUnlocked={() => {\n set('emailConfirm', '');\n controls.current.email?.focus();\n }}\n />\n );\n }\n return (\n <FormField\n key={field}\n id={fieldId(field)}\n label={labels.emailConfirm}\n required\n error={errorFor('emailConfirm')}\n announceError={!summary.lists('emailConfirm')}\n data-field=\"emailConfirm\"\n >\n <EmailInput\n ref={emailConfirmField.ref}\n name={name('emailConfirm')}\n disableBuiltInValidation\n onChange={emailConfirmField.quiet((event) =>\n set('emailConfirm', event.target.value),\n )}\n onBlur={() => {\n leave('emailConfirm');\n emailMatch.confirmProps.onBlur();\n }}\n {...clipboard('emailConfirm')}\n />\n </FormField>\n );\n case 'password':\n return (\n <FormField\n key={field}\n id={fieldId(field)}\n label={labels.password}\n required\n error={errorFor('password')}\n announceError={!summary.lists('password')}\n data-field=\"password\"\n >\n {/* PasswordInput names itself \"password\" when given no\n name; an empty one keeps a field out of the post. */}\n <PasswordInput\n ref={control.password}\n name={name('password') ?? ''}\n autoComplete=\"new-password\"\n requirements={requirements}\n value={values.password}\n onChange={(event) => set('password', event.target.value)}\n onBlur={() => leave('password')}\n {...clipboard('password')}\n />\n </FormField>\n );\n case 'passwordConfirm':\n return (\n <FormField\n key={field}\n id={fieldId(field)}\n label={labels.passwordConfirm}\n required\n error={errorFor('passwordConfirm')}\n announceError={!summary.lists('passwordConfirm')}\n data-field=\"passwordConfirm\"\n >\n <PasswordInput\n ref={control.passwordConfirm}\n name={name('passwordConfirm') ?? ''}\n autoComplete=\"new-password\"\n value={values.passwordConfirm}\n onChange={(event) => set('passwordConfirm', event.target.value)}\n onBlur={() => {\n leave('passwordConfirm');\n passwordMatch.confirmProps.onBlur();\n }}\n {...clipboard('passwordConfirm')}\n />\n </FormField>\n );\n case 'phone':\n return (\n <FormField\n key={field}\n id={fieldId(field)}\n label={labels.phone}\n required\n error={errorFor('phone')}\n announceError={!summary.lists('phone')}\n data-field=\"phone\"\n data-verification={verificationStep(phoneVerification)}\n >\n {/* The visible input holds the number as typed. In a native\n post a hidden input carries the full international\n number instead. */}\n {phoneVerification.enabled ? (\n <div className=\"ds:@container/verify ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:flex-col ds:items-start ds:gap-[var(--spacing-sm)] ds:@[384px]/verify:flex-row\">\n <div className=\"ds:min-w-0 ds:w-full ds:@[384px]/verify:w-auto ds:@[384px]/verify:flex-1\">\n {phoneInput}\n </div>\n <VerificationAction\n state={phoneVerification}\n canSend={values.phone !== '' && phonePossible}\n />\n </div>\n <VerificationPanel\n field=\"phone\"\n state={phoneVerification}\n changeWhenVerified\n onUnlocked={() => controls.current.phone?.focus()}\n onVerified={() => controls.current.phone?.focus()}\n />\n </div>\n ) : (\n phoneInput\n )}\n </FormField>\n );\n case 'branch':\n return (\n <FormField\n key={field}\n id={fieldId(field)}\n label={labels.branch}\n required\n error={errorFor('branch')}\n announceError={!summary.lists('branch')}\n data-field=\"branch\"\n >\n <Select\n ref={control.branch}\n name={name('branch')}\n options={branches ?? []}\n value={values.branch}\n onValueChange={(value) => set('branch', value)}\n />\n </FormField>\n );\n }\n };\n\n return (\n <div\n ref={ref}\n {...rest}\n data-component=\"registration-form\"\n className={registrationFormVariants({ className })}\n >\n <Card variant=\"elevated\">\n <Card.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-lg)]\">\n <div className={headerVariants({ logo: showLogo })}>\n <div className={headingBlockVariants({ centred: showLogo })}>\n {/* The page's logo: read out once, before the heading. */}\n {showLogo && (\n <BrandMark motion={logoMotion} label={BRAND_NAME} />\n )}\n <Heading id={titleId} className=\"type-title-card\">\n {title ?? t('registrationForm.title')}\n </Heading>\n {description && (\n <p className=\"type-body-sm ds:text-[var(--muted-foreground)]\">\n {description}\n </p>\n )}\n </div>\n {devBypass && (devBypass.values || devBypass.onClick) && (\n <div className={shortcutVariants({ corner: showLogo })}>\n <DevBypassButton\n label={devBypass.label}\n onClick={runDevBypass}\n />\n </div>\n )}\n </div>\n\n {hasHostContent ? (\n <div\n data-slot=\"host-content\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\"\n >\n {notice ? (\n <Alert variant=\"info\" announce=\"off\">\n <Alert.Description>{notice}</Alert.Description>\n </Alert>\n ) : null}\n {benefitLines.length > 0 ? (\n <List density=\"compact\">\n {benefitLines.map((benefit, index) => (\n <List.Item\n key={`${index}-${benefit}`}\n leading={<Check aria-hidden=\"true\" />}\n title={benefit}\n />\n ))}\n </List>\n ) : null}\n {children}\n </div>\n ) : null}\n\n {/* Always POST, in both modes: should the script ever fail to\n run, the browser must not put a password in the address. */}\n <form\n ref={form}\n noValidate\n method=\"post\"\n action={formAction}\n aria-labelledby={titleId}\n aria-busy={busy || undefined}\n onSubmit={submit.handleSubmit}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\"\n >\n <ErrorSummary\n ref={summary.ref}\n headingLevel={(headingLevel + 1) as 2 | 3 | 4}\n // The message about the whole form is read with it.\n aria-describedby={formError ? formMessageId : undefined}\n errors={summary.listed.map((field) => {\n const message = errorFor(field) ?? '';\n return {\n field,\n message,\n // \"This field is required.\" does not say which field:\n // the summary names it.\n label:\n message === required && field !== 'terms'\n ? labels[field]\n : undefined,\n targetId: fieldId(field),\n };\n })}\n />\n\n {formError && (\n <Alert\n ref={formMessage}\n id={formMessageId}\n variant=\"error\"\n announce={formMessageAnnounce}\n tabIndex={-1}\n data-field=\"form\"\n className={formMessageVariants()}\n >\n <Alert.Description>{formError}</Alert.Description>\n </Alert>\n )}\n\n {layOutRows((field) =>\n field === 'emailConfirm'\n ? shows(field) || changeSlot\n : shows(field),\n ).map((row) => (\n <div\n key={row[0]}\n className={rowVariants({\n columns: row.length === 2 ? 'two' : 'one',\n })}\n >\n {row.map(renderField)}\n </div>\n ))}\n {native && showsPhone && fieldNames.phone && (\n <input\n type=\"hidden\"\n name={fieldNames.phone}\n value={values.phone}\n />\n )}\n {native && fieldNames.captcha && (\n <input\n ref={captchaInput}\n type=\"hidden\"\n name={fieldNames.captcha}\n defaultValue=\"\"\n />\n )}\n {extraFields\n .filter(([extraName]) => !ownNames.has(extraName))\n .map(([extraName, value]) => (\n <input\n key={extraName}\n type=\"hidden\"\n name={extraName}\n value={value}\n />\n ))}\n\n {shows('terms') && (\n <div\n id={fieldId('terms')}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n data-field=\"terms\"\n >\n {termsDescription && (\n <p\n id={termsDescriptionId}\n className=\"type-body-sm ds:text-[var(--muted-foreground)]\"\n >\n {termsDescription}\n </p>\n )}\n <Checkbox\n ref={control.terms}\n name={name('terms')}\n value=\"1\"\n checked={values.terms}\n onCheckedChange={(next) => set('terms', next === true)}\n aria-required=\"true\"\n aria-invalid={termsError ? true : undefined}\n aria-describedby={termsDescribedBy}\n label={\n <>\n {termsLabel ?? (\n <Trans\n i18n={i18n}\n ns=\"ui\"\n i18nKey=\"registrationForm.terms\"\n components={{\n terms: termsLink ? (\n <InlineLink href={termsLink} newTab />\n ) : (\n <PlainText />\n ),\n privacy: privacyLink ? (\n <InlineLink href={privacyLink} newTab />\n ) : (\n <PlainText />\n ),\n }}\n />\n )}\n <span\n aria-hidden=\"true\"\n className={requiredMarkVariants()}\n >\n *\n </span>\n </>\n }\n />\n {termsError && (\n <p\n id={termsErrorId}\n // Quiet while the summary lists it: the summary reads it.\n role={summary.lists('terms') ? undefined : 'alert'}\n data-slot=\"error\"\n className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-body-sm ds:text-destructive\"\n >\n <CircleAlert\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0\"\n />\n <span>{termsError}</span>\n </p>\n )}\n </div>\n )}\n\n <Button\n type=\"submit\"\n intent=\"primary\"\n size=\"lg\"\n loading={busy}\n className=\"ds:w-full\"\n data-action=\"submit\"\n // Not native `disabled`: a press still lists what is\n // missing in the summary and moves focus to it.\n aria-disabled={emailNeedsCode || phoneNeedsCode || undefined}\n >\n {submitLabel ?? t('registrationForm.submit')}\n </Button>\n {/* The spinner is decorative and the button is only\n marked unavailable while busy, so say it in words. Always mounted: a live\n region announces a change, not its first content. */}\n <p role=\"status\" className=\"ds:sr-only\">\n {busy ? t('chat.message.status.sending') : ''}\n </p>\n\n {loginLink && (\n <p className=\"type-body-sm ds:text-center ds:text-[var(--muted-foreground)]\">\n <Trans\n i18n={i18n}\n ns=\"ui\"\n i18nKey=\"registrationForm.login\"\n components={{\n login: (\n <InlineLink\n href={loginLink}\n weight=\"strong\"\n action=\"login\"\n />\n ),\n }}\n />\n </p>\n )}\n\n {/* Last, so its badge comes after the button and the login\n link in the tab order. Out of the flow: it takes no\n space, so it must not take a gap either. The card says\n when the check fails, so the widget stays quiet. */}\n {recaptchaSiteKey && (\n <div className=\"ds:absolute\">\n <RecaptchaWidget\n ref={submit.captcha.ref}\n siteKey={recaptchaSiteKey}\n size=\"invisible\"\n announceStatus={false}\n onChange={submit.captcha.onChange}\n onError={submit.captcha.onError}\n />\n </div>\n )}\n </form>\n </Card.Body>\n </Card>\n </div>\n );\n },\n);\nRegistrationForm.displayName = 'RegistrationForm';\n"],"names":["FAILURES","FAILED","positiveNumber","input","toResult","body","raw","result","retry","resend","retryAfterHeader","response","header","postVerification","url","payload","isSameSiteHref","isDevelopment","limited","base","verificationHandlers","config","sendUrl","verifyUrl","value","code","DEFAULT_CODE_LENGTH","DEFAULT_RESEND_SECONDS","failureOf","useContactVerification","codeLength","status","setStatus","useState","setCodeState","failure","setFailure","cooldown","setCooldown","devCode","setDevCode","sentTo","setSentTo","latest","useRef","request","original","unlocked","setUnlocked","verifiedByHost","verified","told","useEffect","_b","_a","timer","left","sameValue","a","b","reset","useCallback","current","lastValue","send","target","id","verify","typed","length","entered","changeable","unlock","setCode","next","useFailureMessage","t","useTranslation","useSendFailureMessage","state","message","VerificationAction","canSend","sending","waiting","jsx","Button","VerificationPanel","field","canChange","changeWhenVerified","onUnlocked","onVerified","panel","open","verifying","complete","focusFirstBox","previous","lastFailure","before","announcement","setAnnouncement","wasWaiting","isEmail","sentText","changeText","verifiedText","jsxs","CircleCheck","Pencil","Fragment","Alert","FormField","OTPInput","VerificationChangeSlot","REGISTRATION_FORM_FIELDS","registrationFormVariants","cva","rowVariants","headerVariants","headingBlockVariants","shortcutVariants","inlineLinkVariants","formMessageVariants","requiredMarkVariants","DEFAULT_PASSWORD_POLICY","BRAND_NAME","MARKED","OTHER_TAGS","linkTo","href","isSafeHref","hasMessage","errors","isPossiblePhone","e164","parsePhoneNumberFromString","InlineLink","newTab","weight","action","children","PlainText","verificationStep","FIELD_PAIRS","layOutRows","shows","rows","pair","row","last","RegistrationForm","forwardRef","title","description","headingLevel","showLogo","logoMotion","fields","initialValues","emailReadOnly","emailDescription","blockPaste","blockCopy","branches","passwordPolicy","termsHref","privacyHref","termsLabelNode","termsDescriptionNode","termsLabelText","termsDescriptionText","notice","benefits","loginHref","recaptchaSiteKey","submitLabel","submitting","devBypass","onSubmit","fieldNames","hiddenFields","verification","requireVerification","className","rest","ref","i18n","titleId","useId","fieldIdBase","fieldId","termsErrorId","termsDescriptionId","formMessageId","native","hasBranches","hadEmail","emailLocked","emailVerified","values","setValues","phonePossible","setPhonePossible","touched","setTouched","submitted","setSubmitted","serverErrors","setServerErrors","emailVerification","phoneVerification","phoneVerified","shown","changeSlot","emailNeedsCode","phoneNeedsCode","emailSendFailure","phoneSendFailure","set","leave","emptyPasswords","clipboard","requirements","usePasswordRequirements","emailMatch","useFieldMatch","passwordMatch","invalid","rule","due","required","labels","whenDue","ownErrors","sendFailures","errorFor","controls","control","useMemo","bind","node","emailField","useStateBackedInput","emailConfirmField","formMessage","focusTargetFor","messages","openedWithFieldMessage","summary","useErrorSummary","focusRequest","setFocusRequest","showsPhone","onBlur","form","captchaInput","submitRequest","setSubmitRequest","runDevBypass","filled","email","kept","submit","useRegistrationSubmit","captchaToken","text","answer","busy","captchaFailed","name","Heading","termsLink","privacyLink","loginLink","marked","parts","part","index","tag","words","termsLabel","termsDescription","benefitLines","hasHostContent","formAction","formError","formMessageAnnounce","useFormMessageAnnounce","termsError","termsDescribedBy","ownNames","extraFields","clashes","extraName","emailReadOnlyNow","emailInput","EmailInput","event","phoneInput","PhoneInput","meta","renderField","StateBackedTextInput","PasswordInput","Select","Card","BrandMark","DevBypassButton","List","benefit","Check","ErrorSummary","Checkbox","Trans","CircleAlert","RecaptchaWidget"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-webhook-action-BvVPZVpG.js","sources":["../../node_modules/lucide-react/dist/esm/icons/key-round.mjs","../../src/patterns/workflow-webhook-action/workflow-webhook-action.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z\",\n key: \"1s6t7t\"\n }\n ],\n [\"circle\", { cx: \"16.5\", cy: \"7.5\", r: \".5\", fill: \"currentColor\", key: \"w0ekpg\" }]\n];\nconst KeyRound = createLucideIcon(\"key-round\", __iconNode);\n\nexport { __iconNode, KeyRound as default };\n//# sourceMappingURL=key-round.mjs.map\n","/* -------------------------------------------------------------------- */\n/* WorkflowWebhookAction — the fields of a workflow's webhook step. */\n/* */\n/* The step sends a signed message to another app, such as Link, each */\n/* time a patient reaches it. The fields ask for what most practices */\n/* need, the address and the secret, and keep the extra parameters in */\n/* an Advanced section that stays closed until it is used. */\n/* */\n/* It renders fields, not a form: the host keeps its own form, title */\n/* and Save button around it. Given `fieldNames`, the inputs post to the */\n/* host's own names, so a server form needs no change. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cva } from 'class-variance-authority';\nimport { Check, CircleAlert, Copy, KeyRound, Send } from 'lucide-react';\nimport { CodeBlock } from '../../components/_shared/code-block';\nimport { Accordion } from '../../components/accordion';\nimport { Alert } from '../../components/alert';\nimport { Badge } from '../../components/badge';\nimport { Button, IconButton } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { Checkbox } from '../../components/checkbox';\nimport { FieldArray } from '../../components/field-array';\nimport { FormField } from '../../components/form-field';\nimport { PasswordInput } from '../../components/password-input';\nimport { TextInput } from '../../components/text-input';\nimport { TokenInsertMenu } from '../../components/token-insert-menu';\nimport { useCopyToClipboard } from '../../hooks/use-copy-to-clipboard';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** The fields of the step, in the order they appear. */\nexport const WORKFLOW_WEBHOOK_ACTION_FIELDS = [\n 'url',\n 'secret',\n 'legalBasisConfirmed',\n 'parameters',\n] as const;\n\nexport type WorkflowWebhookActionField =\n (typeof WORKFLOW_WEBHOOK_ACTION_FIELDS)[number];\n\n/** One parameter value as the platform stores it: a flat scalar. */\nexport type WorkflowWebhookParameterValue = string | number | boolean | null;\n\n/** What the step holds now. Mirrors the platform's\n * `SendHttpRequestWorkflowActionDto`. */\nexport interface WorkflowWebhookActionValues {\n /** Where the message goes: platform `url`. */\n url: string;\n /**\n * A new signing secret: platform `secret`, stored encrypted as\n * `encryptedSecret`. Empty means \"keep the saved one\". The server never\n * sends a saved secret back.\n */\n secret: string;\n /** The extra parameters: platform `parameters`, a flat map of scalars. */\n parameters: Record<string, WorkflowWebhookParameterValue>;\n /** The consent box: platform `legalBasisConfirmed`. */\n legalBasisConfirmed: boolean;\n}\n\n/** Values to show when the fields open. There is no secret here, on\n * purpose: a saved secret is never sent back to the browser. */\nexport type WorkflowWebhookActionInitialValues = Partial<\n Omit<WorkflowWebhookActionValues, 'secret'>\n>;\n\n/** Messages from the server, already translated, one per field. */\nexport type WorkflowWebhookActionErrors = Partial<\n Record<WorkflowWebhookActionField, string>\n>;\n\n/** The host's own form field names, for a native form post. */\nexport type WorkflowWebhookActionFieldNames = Record<\n WorkflowWebhookActionField,\n string\n>;\n\n/** A variable the user can insert into a parameter value. */\nexport interface WorkflowWebhookActionPlaceholder {\n /** The code the server replaces, such as `[[NOME]]`. */\n value: string;\n /** What the user reads, translated, such as \"First name\". */\n label: string;\n}\n\n/**\n * What a test message got back, as the host's server saw it.\n * `answered`: the app replied with this HTTP status. `unreachable`: no\n * reply at all (the address does not resolve, refuses, times out or has\n * no valid certificate). `message` replaces the fields' own words, already\n * translated, when the server knows better.\n */\nexport type WorkflowWebhookTestResult =\n | { outcome: 'answered'; status: number; message?: string }\n | { outcome: 'unreachable'; message?: string };\n\nexport interface WorkflowWebhookActionProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'children' | 'onChange'\n> {\n /**\n * Host content above the fields, such as the plan notice (\"Included in\n * the trial and the Elite plans\"). Nothing in it is posted.\n */\n children?: ReactNode;\n /**\n * Values to show when the fields open. Read once. Parameters keep the\n * order and the names they are given; a number beyond\n * `Number.MAX_SAFE_INTEGER` has already lost precision by the time it\n * arrives here.\n */\n initialValues?: WorkflowWebhookActionInitialValues;\n /**\n * True when the step already has a secret. The secret field is then\n * optional: left empty, the saved secret stays.\n */\n hasSavedSecret?: boolean;\n /**\n * Messages from the server, already translated. A field's message shows\n * until the user changes that field; when the fields open with\n * messages, focus goes to the first one. A message on `parameters`\n * opens the Advanced section.\n *\n * A React host keeps `errors` in state: each new object is a new answer\n * from the server, shown even when its words match the last one.\n */\n errors?: WorkflowWebhookActionErrors;\n /**\n * For a native form post: the host's own field names. The parameters\n * post as one JSON object, or an empty string when there are none. The\n * consent box posts `1` when ticked and nothing when not. The fields\n * must sit inside the host's `<form>`.\n */\n fieldNames?: WorkflowWebhookActionFieldNames;\n /**\n * The variables the user can insert into a parameter value, listed in\n * Advanced with a copy button each. Default: the three the platform\n * replaces in a webhook step (salutation, first name, last name), with\n * the kit's own labels. An empty list hides the menu and the list.\n */\n placeholders?: ReadonlyArray<WorkflowWebhookActionPlaceholder>;\n /**\n * Shows \"Send test\". Called with the values when the user asks for a\n * test, once the address and the secret pass their checks; the host's\n * server sends a sample message (invented IDs, no patient data, marked\n * as a test) signed with that secret, or with the saved one when\n * `secret` is empty, and resolves with what came back. A rejected\n * promise reads as \"the test could not be sent\". Without it, no button.\n */\n onSendTest?: (\n values: WorkflowWebhookActionValues,\n ) => Promise<WorkflowWebhookTestResult>;\n /** For React hosts: called with the values after each change. */\n onValueChange?: (values: WorkflowWebhookActionValues) => void;\n /**\n * How the \"What Alfadocs sends\" card lays out the message body and its\n * headers. `two-column` (default): side by side once the fields are\n * 720px wide; narrower, as on a phone, one above the other.\n * `one-column`: always one above the other, for a narrow card or a side\n * panel.\n */\n layout?: 'two-column' | 'one-column';\n}\n\n/* -------------------------------------------------------------------- */\n/* Styles */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n 'ds:flex ds:w-full ds:flex-col ds:gap-[var(--spacing-lg)] ds:text-start ds:text-[var(--foreground)]',\n);\n\n// Two columns: the fields side by side, read left to right.\n// Side by side when wide: two to a row, or three for the variables so\n// none of the three sits alone.\nconst fieldsGridVariants = cva(\n 'ds:m-0 ds:grid ds:gap-x-[var(--spacing-xl)] ds:gap-y-[var(--spacing-md)]',\n {\n variants: {\n columns: {\n 1: 'ds:grid-cols-1',\n 2: 'ds:grid-cols-2',\n 3: 'ds:grid-cols-3',\n },\n },\n defaultVariants: { columns: 1 },\n },\n);\n\nconst referenceSectionVariants = cva(\n 'ds:flex ds:min-w-0 ds:flex-col ds:gap-[var(--spacing-sm)]',\n);\n\nconst sectionHeadingVariants = cva('type-title-item ds:text-foreground');\n\nconst fieldNameVariants = cva(\n 'ds:min-w-0 ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)] ds:font-mono type-body-sm ds:text-foreground ds:[overflow-wrap:anywhere]',\n);\n\nconst helpVariants = cva('type-body-sm ds:text-muted-foreground');\n\nconst errorVariants = cva(\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-body-sm ds:text-destructive',\n);\n\nconst parameterRowVariants = cva(\n 'ds:grid ds:grid-cols-1 ds:gap-[var(--spacing-sm)] ds:sm:grid-cols-2',\n);\n\n/* -------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------- */\n\n/** The platform posts only to an address that starts with exactly this:\n * `ResolveSafeDestinationService::isHttpsUrl`. */\nconst HTTPS = 'https://';\n\n/** The platform's limit on the address (`SendHttpRequestWorkflowActionType`). */\nconst URL_MAX_LENGTH = 2048;\n\n/** From this width the fields every message carries sit two to a row:\n * room for two readable descriptions. The pattern's own width, not the\n * window's, so it fits whatever space the host gives. */\nconst TWO_COLUMN_MIN_WIDTH = 720;\n\n/** The variables the platform replaces in a parameter value, the same in\n * every language: `GetPlaceholdersForContextService`, webhook context. */\nconst PLATFORM_VARIABLES = {\n salutation: '[[TITOLO]]',\n firstName: '[[NOME]]',\n lastName: '[[COGNOME]]',\n} as const;\n\n/* The example message. Its shape is the platform's\n * (`SendHttpRequestService`, `HmacSignature`); every value is invented. */\nconst EXAMPLE_IDEMPOTENCY_KEY = 'wf12-e345-a67';\nconst EXAMPLE_BODY = {\n sentAt: '2026-10-12T09:00:00+02:00',\n idempotencyKey: EXAMPLE_IDEMPOTENCY_KEY,\n practiceId: 1234,\n workflowId: 12,\n workflowActionId: 67,\n workflowEnrollmentId: 345,\n patientId: 5678,\n};\nconst EXAMPLE_HEADERS = [\n 'Content-Type: application/json',\n `X-AlfaDocs-Idempotency-Key: ${EXAMPLE_IDEMPOTENCY_KEY}`,\n 'X-AlfaDocs-Request-Timestamp: 1791788400000',\n 'X-AlfaDocs-Signature: sha256=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08',\n].join('\\n');\n\ninterface ParameterRow {\n /** Opaque and stable for the row's life: never the name or value. */\n key: string;\n name: string;\n value: string;\n /** What the row arrived with, kept so a saved parameter posts back\n * exactly as it was: a number or boolean as one, not as text. */\n original?: { name: string; value: WorkflowWebhookParameterValue };\n}\n\nconst textOf = (value: WorkflowWebhookParameterValue): string =>\n value === null ? '' : String(value);\n\nconst isUntouched = (row: ParameterRow): boolean =>\n row.original !== undefined &&\n row.name === row.original.name &&\n row.value === textOf(row.original.value);\n\n/**\n * The rows as the server stores them, in the user's order. Names are kept\n * as typed. A new row without a name is left out: the checks stop a\n * submit before that can lose a value.\n */\nconst parameterEntries = (\n rows: ReadonlyArray<ParameterRow>,\n): Array<[string, WorkflowWebhookParameterValue]> =>\n rows.flatMap((row): Array<[string, WorkflowWebhookParameterValue]> => {\n if (row.original !== undefined && isUntouched(row)) {\n return [[row.original.name, row.original.value]];\n }\n if (row.name.trim() === '') return [];\n return [[row.name, row.value]];\n });\n\n/** One JSON object, written by hand so the order is the user's: a plain\n * object would move number-like names to the front. */\nconst parametersJsonOf = (\n entries: ReadonlyArray<[string, WorkflowWebhookParameterValue]>,\n): string =>\n entries.length === 0\n ? ''\n : `{${entries\n .map(\n ([name, value]) => `${JSON.stringify(name)}:${JSON.stringify(value)}`,\n )\n .join(',')}}`;\n\n/** 32 random bytes as hex: 64 characters the receiving app can store. */\nconst generateSecret = (): string => {\n const bytes = new Uint8Array(32);\n globalThis.crypto.getRandomValues(bytes);\n return Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join(\n '',\n );\n};\n\ntype FocusTarget =\n | {\n kind: 'url' | 'secret' | 'legal' | 'copy' | 'add' | 'parametersError';\n }\n | { kind: 'parameter'; key: string };\n\n/** Where focus goes when the fields open with the server's messages. */\nconst firstServerMessage = (\n errors: WorkflowWebhookActionErrors | undefined,\n): FocusTarget | null => {\n if (errors?.url) return { kind: 'url' };\n if (errors?.secret) return { kind: 'secret' };\n if (errors?.legalBasisConfirmed) return { kind: 'legal' };\n if (errors?.parameters) return { kind: 'parametersError' };\n return null;\n};\n\ninterface SentFieldProps {\n /** The field or header name, as the receiving app reads it. */\n name: string;\n /** What it holds, in plain words. */\n description: string;\n /** Told whether the copy worked, so the fields can say so. */\n onCopied: (copied: boolean) => void;\n}\n\n/** One field every message carries: its name to copy, then its meaning.\n * Renders a `<dl>` group, so it sits inside a `<dl>`. */\nfunction SentField({ name, description, onCopied }: SentFieldProps) {\n const { t } = useTranslation('ui');\n // \"Copy [[NOME]]\" alone does not say what it is: the meaning describes it.\n const descriptionId = useId();\n const { status, copy } = useCopyToClipboard();\n const copied = status === 'copied';\n const failed = status === 'error';\n return (\n <div className=\"ds:flex ds:min-w-0 ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n <dt className=\"ds:flex ds:min-w-0 ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\">\n <code dir=\"ltr\" className={fieldNameVariants()}>\n {name}\n </code>\n <IconButton\n icon={copied ? <Check /> : failed ? <CircleAlert /> : <Copy />}\n size=\"sm\"\n intent=\"ghost\"\n aria-label={t('keyValuePair.copy', { label: name })}\n aria-describedby={descriptionId}\n data-action=\"copy-field\"\n data-copied={copied ? 'true' : undefined}\n onClick={() => void copy(name).then(onCopied)}\n />\n {/* Seen, not heard: the fields announce the copy once. */}\n {copied ? (\n <span aria-hidden=\"true\" className=\"type-body-sm ds:text-success\">\n {t('copyField.copied')}\n </span>\n ) : failed ? (\n <span aria-hidden=\"true\" className=\"type-body-sm ds:text-destructive\">\n {t('copyField.copyFailed')}\n </span>\n ) : null}\n </dt>\n <dd\n id={descriptionId}\n className=\"ds:m-0 type-body-sm ds:text-muted-foreground\"\n >\n {description}\n </dd>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\n/**\n * The fields of a workflow's webhook step. Mount it inside the host's\n * form, between the page title and the Save button.\n */\nexport const WorkflowWebhookAction = forwardRef<\n HTMLDivElement,\n WorkflowWebhookActionProps\n>(\n (\n {\n children,\n initialValues,\n hasSavedSecret = false,\n errors,\n fieldNames,\n placeholders,\n onSendTest,\n onValueChange,\n layout = 'two-column',\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n\n // Every message's fields, in the order the receiving app most likely\n // needs them: the body the platform's `SendHttpRequestService` builds.\n const sentFields: ReadonlyArray<readonly [string, string]> = [\n ['patientId', t('workflowWebhookAction.sent.patientId')],\n ['practiceId', t('workflowWebhookAction.sent.practiceId')],\n ['workflowId', t('workflowWebhookAction.sent.workflowId')],\n ['workflowActionId', t('workflowWebhookAction.sent.workflowActionId')],\n [\n 'workflowEnrollmentId',\n t('workflowWebhookAction.sent.workflowEnrollmentId'),\n ],\n ['sentAt', t('workflowWebhookAction.sent.sentAt')],\n ['idempotencyKey', t('workflowWebhookAction.sent.idempotencyKey')],\n ['parameters', t('workflowWebhookAction.sent.parameters')],\n ];\n // Every message's headers: the platform's `HmacSignature` and sender.\n const sentHeaders: ReadonlyArray<readonly [string, string]> = [\n ['X-AlfaDocs-Signature', t('workflowWebhookAction.headers.signature')],\n [\n 'X-AlfaDocs-Request-Timestamp',\n t('workflowWebhookAction.headers.timestamp'),\n ],\n [\n 'X-AlfaDocs-Idempotency-Key',\n t('workflowWebhookAction.headers.idempotency'),\n ],\n ];\n const legalErrorId = useId();\n const bodyLabelId = useId();\n const headersLabelId = useId();\n const variablesLabelId = useId();\n const testHelpId = useId();\n\n // The variables a value may carry: the host's, or the platform's three.\n const variables: ReadonlyArray<WorkflowWebhookActionPlaceholder> =\n placeholders ?? [\n {\n value: PLATFORM_VARIABLES.salutation,\n label: t('workflowWebhookAction.variableSalutation'),\n },\n {\n value: PLATFORM_VARIABLES.firstName,\n label: t('workflowWebhookAction.variableFirstName'),\n },\n {\n value: PLATFORM_VARIABLES.lastName,\n label: t('workflowWebhookAction.variableLastName'),\n },\n ];\n\n /* ------------------------------ State ----------------------------- */\n\n const keyCounter = useRef(0);\n const nextKey = () => {\n keyCounter.current += 1;\n return `parameter-${keyCounter.current}`;\n };\n\n const [url, setUrl] = useState(() => initialValues?.url ?? '');\n const [secret, setSecret] = useState('');\n // True from a generated secret until the user changes it: the field\n // then says to copy it into the app now.\n const [generated, setGenerated] = useState(false);\n const [rows, setRows] = useState<ParameterRow[]>(() =>\n Object.entries(initialValues?.parameters ?? {}).map(([name, value]) => {\n keyCounter.current += 1;\n return {\n key: `parameter-${keyCounter.current}`,\n name,\n value: textOf(value),\n original: { name, value },\n };\n }),\n );\n const [legal, setLegal] = useState(\n () => initialValues?.legalBasisConfirmed ?? false,\n );\n const [advancedOpen, setAdvancedOpen] = useState(\n () =>\n Object.keys(initialValues?.parameters ?? {}).length > 0 ||\n Boolean(errors?.parameters),\n );\n\n // A field the user has left, and whether a submit has been tried. A\n // message shows once either is true.\n const [touched, setTouched] = useState<Record<string, boolean>>({});\n const [submitted, setSubmitted] = useState(false);\n const [serverErrors, setServerErrors] =\n useState<WorkflowWebhookActionErrors>(() => errors ?? {});\n const [announcement, setAnnouncement] = useState('');\n // The server has answered with messages: focus goes to the first, and\n // the rest stay quiet, as after a refused submit.\n // A test stopped at a field: focus reads its message, the rest stay\n // quiet, as after a refused submit.\n const [testChecked, setTestChecked] = useState(false);\n const [answered, setAnswered] = useState(() =>\n Object.values(errors ?? {}).some(Boolean),\n );\n\n // A new `errors` object is a new answer from the server.\n const lastErrors = useRef(errors);\n useEffect(() => {\n if (errors === lastErrors.current) return;\n lastErrors.current = errors;\n setServerErrors(errors ?? {});\n if (errors?.parameters) setAdvancedOpen(true);\n setAnswered(Object.values(errors ?? {}).some(Boolean));\n setFocusRequest(firstServerMessage(errors));\n }, [errors]);\n\n const leave = (field: string) =>\n setTouched((previous) =>\n previous[field] ? previous : { ...previous, [field]: true },\n );\n // The server's message was about the old value.\n const forget = (field: WorkflowWebhookActionField) =>\n setServerErrors((previous) =>\n previous[field] ? { ...previous, [field]: undefined } : previous,\n );\n\n /* ---------------------------- Refs -------------------------------- */\n\n const rootRef = useRef<HTMLDivElement | null>(null);\n const urlInput = useRef<HTMLInputElement>(null);\n const secretInput = useRef<HTMLInputElement>(null);\n const copyButton = useRef<HTMLButtonElement>(null);\n const parametersError = useRef<HTMLDivElement>(null);\n const legalBox = useRef<HTMLButtonElement>(null);\n const liveRegion = useRef<HTMLSpanElement>(null);\n const nameInputs = useRef(new Map<string, HTMLInputElement>());\n const valueInputs = useRef(new Map<string, HTMLInputElement>());\n // Values the user has been in. An input keeps its caret when it loses\n // focus, so a detail goes where the user left off; a value never\n // visited gets it at the end.\n const visitedValues = useRef(new Set<string>());\n // Where the caret goes after an insert, once the new value is drawn.\n const pendingCaret = useRef<{ key: string; position: number } | null>(null);\n useEffect(() => {\n const pending = pendingCaret.current;\n if (!pending) return;\n pendingCaret.current = null;\n valueInputs.current\n .get(pending.key)\n ?.setSelectionRange(pending.position, pending.position);\n });\n\n // Measured before the first paint, so the layout never jumps.\n const [fitsTwoColumns, setFitsTwoColumns] = useState(false);\n useIsomorphicLayoutEffect(() => {\n const node = rootRef.current;\n if (!node) return;\n const measure = () =>\n setFitsTwoColumns(\n node.getBoundingClientRect().width >= TWO_COLUMN_MIN_WIDTH,\n );\n measure();\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(measure);\n observer.observe(node);\n return () => observer.disconnect();\n }, []);\n\n const twoColumns = layout === 'two-column' && fitsTwoColumns;\n\n const setRootRef = useCallback(\n (node: HTMLDivElement | null) => {\n rootRef.current = node;\n if (typeof ref === 'function') ref(node);\n else if (ref) ref.current = node;\n },\n [ref],\n );\n\n /**\n * Says something to a screen reader. Cleared first, so the same words\n * twice are read twice. While a menu is open the rest of the page is\n * hidden from screen readers, so the words wait until it has closed.\n */\n const announce = (message: string) => {\n setAnnouncement('');\n let frames = 0;\n const speak = () => {\n const hidden = liveRegion.current?.closest('[aria-hidden=\"true\"]');\n if (hidden && frames < 60) {\n frames += 1;\n window.requestAnimationFrame(speak);\n return;\n }\n setAnnouncement(message);\n };\n window.requestAnimationFrame(speak);\n };\n\n /* ---------------------------- Validation -------------------------- */\n\n const urlProblem = (): string | undefined => {\n const value = url.trim();\n if (value === '') return t('workflowWebhookAction.urlRequired');\n let parsed: URL;\n try {\n parsed = new URL(value);\n } catch {\n return t('workflowWebhookAction.urlInvalid');\n }\n if (!value.startsWith(HTTPS)) return t('workflowWebhookAction.urlHttps');\n if (parsed.hostname === '') return t('workflowWebhookAction.urlInvalid');\n if (parsed.username !== '' || parsed.password !== '') {\n return t('workflowWebhookAction.urlCredentials');\n }\n return undefined;\n };\n\n const secretProblem = (): string | undefined =>\n secret.trim() === '' && !hasSavedSecret\n ? t('workflowWebhookAction.secretRequired')\n : undefined;\n\n /** Per row key: a value with no name, or a name used twice. A saved\n * parameter left as it was is never stopped. */\n const rowProblems = (): Map<string, string> => {\n const problems = new Map<string, string>();\n // Every name the post would carry, whatever its row's position: a\n // later saved parameter must stop an edit above it taking its name.\n const counts = new Map<string, number>();\n for (const row of rows) {\n const name = isUntouched(row)\n ? row.name\n : row.name.trim() === ''\n ? null\n : row.name;\n if (name !== null) counts.set(name, (counts.get(name) ?? 0) + 1);\n }\n for (const row of rows) {\n // A saved parameter left as it was is never stopped; the row the\n // user changed is the one to fix.\n if (isUntouched(row)) continue;\n if (row.name.trim() === '') {\n if (row.value !== '')\n problems.set(\n row.key,\n t('workflowWebhookAction.parameterNameRequired'),\n );\n continue;\n }\n if ((counts.get(row.name) ?? 0) > 1)\n problems.set(\n row.key,\n t('workflowWebhookAction.parameterNameDuplicate'),\n );\n }\n return problems;\n };\n\n const legalProblem = (): string | undefined =>\n legal ? undefined : t('workflowWebhookAction.legalBasisRequired');\n\n const due = (field: string) => submitted || touched[field] === true;\n const rowsWithProblems = rowProblems();\n\n const urlError =\n serverErrors.url ?? (due('url') ? urlProblem() : undefined);\n const secretError =\n serverErrors.secret ?? (due('secret') ? secretProblem() : undefined);\n const legalError =\n serverErrors.legalBasisConfirmed ??\n (submitted ? legalProblem() : undefined);\n const rowError = (key: string) =>\n due(`parameter:${key}`) ? rowsWithProblems.get(key) : undefined;\n // After a refused submit focus lands on the first problem, which reads\n // its own message; the others stay quiet rather than all speaking at\n // once. Each is still read when its field has focus.\n const announceErrors = !submitted && !answered && !testChecked;\n\n /** The first field a submit must stop at, in the order they appear. */\n const firstProblem = (): FocusTarget | undefined => {\n if (urlProblem()) return { kind: 'url' };\n if (secretProblem()) return { kind: 'secret' };\n if (legalProblem()) return { kind: 'legal' };\n const row = rows.find((candidate) => rowsWithProblems.has(candidate.key));\n return row ? { kind: 'parameter', key: row.key } : undefined;\n };\n const firstProblemRef = useRef(firstProblem);\n firstProblemRef.current = firstProblem;\n\n /* ------------------------------ Focus ----------------------------- */\n\n // A new object for each request, so asking twice moves focus twice. The\n // effect runs after the change is drawn: a new row, an opened section.\n // A page the server rendered after a refused save opens on its first\n // message.\n const [focusRequest, setFocusRequest] = useState<FocusTarget | null>(() =>\n firstServerMessage(errors),\n );\n useEffect(() => {\n if (!focusRequest) return;\n const target: HTMLElement | null | undefined = (() => {\n switch (focusRequest.kind) {\n case 'url':\n return urlInput.current;\n case 'secret':\n return secretInput.current;\n case 'legal':\n return legalBox.current;\n case 'copy':\n return copyButton.current;\n case 'parametersError':\n return parametersError.current;\n case 'add':\n return rootRef.current?.querySelector<HTMLElement>(\n '[data-slot=\"parameters\"] [data-component=\"field-array\"] > button',\n );\n case 'parameter':\n return nameInputs.current.get(focusRequest.key);\n }\n })();\n target?.focus();\n }, [focusRequest]);\n\n /* ------------------------------ Submit ---------------------------- */\n\n // The host owns the form. Its submit is stopped here while a field has\n // a problem, and focus goes to the first one. A React host's own\n // submit handler should return early when `event.defaultPrevented`.\n // A script that calls `form.submit()` skips this check; the server's\n // own checks still apply.\n useEffect(() => {\n const form = rootRef.current?.closest('form');\n if (!form) return;\n const onSubmit = (event: SubmitEvent) => {\n const first = firstProblemRef.current();\n if (!first) return;\n event.preventDefault();\n setSubmitted(true);\n if (first.kind === 'parameter') setAdvancedOpen(true);\n setFocusRequest({ ...first });\n };\n form.addEventListener('submit', onSubmit);\n return () => form.removeEventListener('submit', onSubmit);\n }, []);\n\n /* ---------------------------- Host sync --------------------------- */\n\n const entries = parameterEntries(rows);\n const parametersJson = parametersJsonOf(entries);\n\n const onValueChangeRef = useRef(onValueChange);\n onValueChangeRef.current = onValueChange;\n // `rows` changes identity on every keystroke; the JSON says when the\n // parameters really changed.\n const entriesRef = useRef(entries);\n entriesRef.current = entries;\n const mounted = useRef(false);\n useEffect(() => {\n if (!mounted.current) {\n mounted.current = true;\n return;\n }\n onValueChangeRef.current?.({\n url,\n secret,\n parameters: Object.fromEntries(entriesRef.current),\n legalBasisConfirmed: legal,\n });\n }, [url, secret, parametersJson, legal]);\n\n /* ----------------------------- Secret ----------------------------- */\n\n // The secret lives in one password field, which keeps it out of the\n // page's markup: never in a `value` attribute, never in a hidden input\n // a copied page or a session recording could read.\n const {\n status: copyStatus,\n copiedValue,\n copy,\n reset: resetCopy,\n } = useCopyToClipboard();\n // \"Copied\" only for the secret in the field now: a new one is not yet\n // in the receiving app.\n const secretCopied = copyStatus === 'copied' && copiedValue === secret;\n const secretCopyFailed = copyStatus === 'error';\n\n const generateNewSecret = () => {\n resetCopy();\n setSecret(generateSecret());\n setGenerated(true);\n forget('secret');\n announce(t('workflowWebhookAction.secretGenerated'));\n setFocusRequest({ kind: 'copy' });\n };\n\n /* ---------------------------- Send test --------------------------- */\n\n type TestState =\n | { kind: 'idle' | 'sending' | 'failed' }\n | { kind: 'done'; result: WorkflowWebhookTestResult };\n const [test, setTest] = useState<TestState>({ kind: 'idle' });\n // A newer test, or a change to what was tested, makes an older answer\n // stale: it is dropped when it arrives.\n const testRun = useRef(0);\n\n const sendTest = async () => {\n if (!onSendTest) return;\n // The two fields a test needs, checked as a save checks them.\n const problem = urlProblem() ? 'url' : secretProblem() ? 'secret' : null;\n if (problem) {\n leave('url');\n leave('secret');\n setTestChecked(true);\n setFocusRequest({ kind: problem });\n return;\n }\n testRun.current += 1;\n const run = testRun.current;\n setTest({ kind: 'sending' });\n try {\n const result = await onSendTest({\n url: url.trim(),\n secret: secretInput.current?.value ?? secret,\n parameters: Object.fromEntries(entries),\n legalBasisConfirmed: legal,\n });\n if (run === testRun.current) finishTest({ kind: 'done', result });\n } catch {\n if (run === testRun.current) finishTest({ kind: 'failed' });\n }\n };\n\n // The answer is said once through the fields' own live region: a\n // result that arrives already filled in is not reliably read. Focus\n // stays on the button while it is busy (a loading Button keeps it).\n const finishTest = (next: TestState) => {\n setTest(next);\n const outcome = describeTest(next);\n if (outcome) announce(outcome.text);\n };\n\n // What was tested has changed: the answer no longer applies.\n const testedText = `${url}\\n${secret}\\n${parametersJson}`;\n const lastTestedText = useRef(testedText);\n useEffect(() => {\n if (testedText === lastTestedText.current) return;\n lastTestedText.current = testedText;\n testRun.current += 1;\n setTest((previous) =>\n previous.kind === 'idle' ? previous : { kind: 'idle' },\n );\n }, [testedText]);\n\n /** The answer in words, and whether it is good news. */\n const describeTest = (\n state: TestState,\n ): { ok: boolean; text: string } | null => {\n if (state.kind === 'failed') {\n return { ok: false, text: t('workflowWebhookAction.testFailed') };\n }\n if (state.kind !== 'done') return null;\n const { result } = state;\n const ok =\n result.outcome === 'answered' &&\n result.status >= 200 &&\n result.status < 300;\n if (result.message) return { ok, text: result.message };\n if (result.outcome === 'unreachable') {\n return { ok, text: t('workflowWebhookAction.testUnreachable') };\n }\n if (ok) {\n return {\n ok,\n text: t('workflowWebhookAction.testSent', { status: result.status }),\n };\n }\n return {\n ok,\n text:\n result.status === 401 || result.status === 403\n ? t('workflowWebhookAction.testCheckSecret', {\n status: result.status,\n })\n : t('workflowWebhookAction.testRejected', {\n status: result.status,\n }),\n };\n };\n\n const copySecret = async () => {\n const ok = await copy(secretInput.current?.value ?? secret);\n announce(ok ? t('copyField.copySuccess') : t('copyField.copyFailed'));\n };\n\n /* --------------------------- Parameters --------------------------- */\n\n const updateRow = (key: string, patch: Partial<ParameterRow>) => {\n setRows((previous) =>\n previous.map((row) => (row.key === key ? { ...row, ...patch } : row)),\n );\n forget('parameters');\n };\n\n const addRow = () => {\n const key = nextKey();\n setRows((previous) => [...previous, { key, name: '', value: '' }]);\n setFocusRequest({ kind: 'parameter', key });\n };\n\n const removeRow = (index: number) => {\n const next = rows.filter((_, position) => position !== index);\n const removed = rows[index];\n if (removed) {\n nameInputs.current.delete(removed.key);\n valueInputs.current.delete(removed.key);\n visitedValues.current.delete(removed.key);\n }\n setRows(next);\n forget('parameters');\n const neighbour = next[index] ?? next[index - 1];\n setFocusRequest(\n neighbour ? { kind: 'parameter', key: neighbour.key } : { kind: 'add' },\n );\n };\n\n const insertPlaceholder = (row: ParameterRow, token: string) => {\n const input = valueInputs.current.get(row.key);\n const visited = input !== undefined && visitedValues.current.has(row.key);\n const start = visited\n ? (input.selectionStart ?? row.value.length)\n : row.value.length;\n const end = visited ? (input.selectionEnd ?? start) : start;\n const value = row.value.slice(0, start) + token + row.value.slice(end);\n pendingCaret.current = { key: row.key, position: start + token.length };\n updateRow(row.key, { value });\n const label = variables.find((item) => item.value === token)?.label;\n announce(\n t('workflowWebhookAction.placeholderInserted', {\n detail: label ?? token,\n }),\n );\n };\n\n /* ------------------------------ Render ---------------------------- */\n\n const announceCopy = (copied: boolean) =>\n announce(copied ? t('copyField.copySuccess') : t('copyField.copyFailed'));\n\n /** The fields of one part of the message, each with its name to copy. */\n const renderFields = (\n labelId: string,\n items: ReadonlyArray<readonly [string, string]>,\n wideColumns: 2 | 3 = 2,\n ) => (\n <dl\n aria-labelledby={labelId}\n className={fieldsGridVariants({\n columns: twoColumns ? wideColumns : 1,\n })}\n >\n {items.map(([name, description]) => (\n <SentField\n key={name}\n name={name}\n description={description}\n onCopied={announceCopy}\n />\n ))}\n </dl>\n );\n\n // The example body carries the user's own parameters, as sent.\n const exampleBody = JSON.stringify(\n { ...EXAMPLE_BODY, parameters: Object.fromEntries(entries) },\n null,\n 2,\n );\n\n /** What every message carries, for whoever sets up the receiving app:\n * each part with an example to copy, then each field to copy. */\n const reference = (\n <div\n data-columns={twoColumns ? 2 : 1}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xl)]\"\n >\n <div className={referenceSectionVariants()}>\n <h4 id={bodyLabelId} className={sectionHeadingVariants()}>\n {t('workflowWebhookAction.bodyHeading')}\n </h4>\n <p className={helpVariants()}>\n {t('workflowWebhookAction.sentDescription')}\n </p>\n <CodeBlock\n language=\"json\"\n code={exampleBody}\n copyLabel={t('workflowWebhookAction.copyBody')}\n />\n {renderFields(bodyLabelId, sentFields)}\n </div>\n\n <div className={referenceSectionVariants()}>\n <h4 id={headersLabelId} className={sectionHeadingVariants()}>\n {t('workflowWebhookAction.headersHeading')}\n </h4>\n <p className={helpVariants()}>\n {t('workflowWebhookAction.headersDescription')}\n </p>\n <CodeBlock\n language=\"http\"\n code={EXAMPLE_HEADERS}\n copyLabel={t('workflowWebhookAction.copyHeaders')}\n />\n {renderFields(headersLabelId, sentHeaders)}\n </div>\n </div>\n );\n\n const native = fieldNames !== undefined;\n const secretDescription = generated\n ? t('workflowWebhookAction.generatedNotice')\n : hasSavedSecret\n ? t('workflowWebhookAction.secretSavedDescription')\n : t('workflowWebhookAction.secretDescription');\n\n return (\n <div\n ref={setRootRef}\n {...rest}\n data-component=\"workflow-webhook-action\"\n data-layout={twoColumns ? 'two-column' : 'one-column'}\n className={rootVariants({ className })}\n >\n {children ? (\n <div\n data-slot=\"host-content\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\"\n >\n {children}\n </div>\n ) : null}\n\n <p className={helpVariants()}>{t('workflowWebhookAction.intro')}</p>\n\n <FormField\n label={t('workflowWebhookAction.url')}\n description={t('workflowWebhookAction.urlDescription')}\n required\n error={urlError}\n announceError={announceErrors}\n data-field=\"url\"\n >\n {/* Text, not `type=\"url\"`: the browser's own check would stop\n the host's form with its own message before ours. An address\n reads left to right in every language. */}\n <TextInput\n ref={urlInput}\n name={native ? fieldNames.url : undefined}\n dir=\"ltr\"\n inputMode=\"url\"\n autoComplete=\"off\"\n spellCheck={false}\n maxLength={URL_MAX_LENGTH}\n placeholder=\"https://\"\n value={url}\n onChange={(event) => {\n setUrl(event.target.value);\n forget('url');\n }}\n onBlur={(event) => {\n if (event.target.value !== '') leave('url');\n }}\n />\n </FormField>\n\n <div\n data-field=\"secret\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\"\n >\n <FormField\n label={t('workflowWebhookAction.secret')}\n description={secretDescription}\n {...(hasSavedSecret ? { optional: true } : { required: true })}\n error={secretError}\n announceError={announceErrors}\n >\n <PasswordInput\n ref={secretInput}\n // PasswordInput names itself \"password\" when given no name.\n name={native ? fieldNames.secret : ''}\n dir=\"ltr\"\n autoComplete=\"new-password\"\n spellCheck={false}\n value={secret}\n onChange={(event) => {\n setSecret(event.target.value);\n setGenerated(false);\n resetCopy();\n forget('secret');\n }}\n onBlur={(event) => {\n if (event.target.value !== '') leave('secret');\n }}\n />\n </FormField>\n <div className=\"ds:flex ds:flex-wrap ds:gap-[var(--spacing-xs)]\">\n <Button\n type=\"button\"\n intent=\"outline\"\n size=\"sm\"\n startIcon={<KeyRound />}\n data-action=\"generate-secret\"\n onClick={generateNewSecret}\n >\n {t('workflowWebhookAction.generate')}\n </Button>\n <Button\n ref={copyButton}\n type=\"button\"\n intent=\"outline\"\n size=\"sm\"\n disabled={secret === ''}\n startIcon={\n secretCopied ? (\n <Check />\n ) : secretCopyFailed ? (\n <CircleAlert />\n ) : (\n <Copy />\n )\n }\n data-action=\"copy-secret\"\n data-copied={secretCopied ? 'true' : undefined}\n onClick={() => void copySecret()}\n >\n {secretCopied\n ? t('copyField.copied')\n : secretCopyFailed\n ? t('copyField.copyFailed')\n : t('workflowWebhookAction.copySecret')}\n </Button>\n </div>\n </div>\n\n {onSendTest ? (\n <div\n data-slot=\"send-test\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\"\n >\n <p id={testHelpId} className={helpVariants()}>\n {t('workflowWebhookAction.testDescription')}\n </p>\n <Button\n type=\"button\"\n intent=\"outline\"\n size=\"sm\"\n startIcon={<Send />}\n loading={test.kind === 'sending'}\n aria-describedby={testHelpId}\n className=\"ds:self-start\"\n data-action=\"send-test\"\n onClick={() => void sendTest()}\n >\n {t('workflowWebhookAction.sendTest')}\n </Button>\n {(() => {\n const outcome = describeTest(test);\n return outcome ? (\n <Alert\n variant={outcome.ok ? 'success' : 'error'}\n announce=\"off\"\n data-slot=\"test-result\"\n data-test-ok={outcome.ok ? 'true' : 'false'}\n >\n <Alert.Description>{outcome.text}</Alert.Description>\n </Alert>\n ) : null;\n })()}\n </div>\n ) : null}\n\n <div\n data-field=\"legalBasisConfirmed\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\"\n >\n <Checkbox\n ref={legalBox}\n name={native ? fieldNames.legalBasisConfirmed : undefined}\n value=\"1\"\n checked={legal}\n onCheckedChange={(next) => {\n setLegal(next === true);\n forget('legalBasisConfirmed');\n }}\n aria-required=\"true\"\n aria-invalid={legalError ? true : undefined}\n aria-describedby={legalError ? legalErrorId : undefined}\n label={t('workflowWebhookAction.legalBasis')}\n />\n {legalError ? (\n <p\n id={legalErrorId}\n role={announceErrors ? 'alert' : undefined}\n data-slot=\"error\"\n className={errorVariants()}\n >\n <CircleAlert\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0\"\n />\n <span>{legalError}</span>\n </p>\n ) : null}\n </div>\n\n {/* Outside the section: closed, its content is not in the page,\n and the parameters must still be posted. */}\n {native ? (\n <input\n type=\"hidden\"\n name={fieldNames.parameters}\n value={parametersJson}\n />\n ) : null}\n\n <div data-field=\"parameters\" data-slot=\"parameters\">\n {/* The elevated card, like the host page's own card. */}\n <Card variant=\"elevated\">\n <Accordion\n type=\"single\"\n collapsible\n value={advancedOpen ? 'advanced' : ''}\n onValueChange={(value: string) =>\n setAdvancedOpen(value === 'advanced')\n }\n >\n <Accordion.Item value=\"advanced\">\n <Accordion.Trigger data-action=\"toggle-advanced\">\n <span className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\">\n <span>{t('workflowWebhookAction.advanced')}</span>\n {entries.length > 0 ? (\n <Badge variant=\"neutral\" size=\"md\">\n {t('workflowWebhookAction.parameterCount', {\n total: entries.length,\n })}\n </Badge>\n ) : null}\n </span>\n </Accordion.Trigger>\n <Accordion.Content>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-lg)]\">\n <p className={helpVariants()}>\n {t('workflowWebhookAction.advancedDescription')}\n </p>\n\n {serverErrors.parameters ? (\n <div\n ref={parametersError}\n tabIndex={-1}\n data-slot=\"error\"\n className=\"ds:outline-none\"\n >\n <Alert variant=\"error\" announce=\"off\">\n <Alert.Description>\n {serverErrors.parameters}\n </Alert.Description>\n </Alert>\n </div>\n ) : null}\n\n <FieldArray\n legend={t('workflowWebhookAction.parametersLegend')}\n items={rows}\n addLabel={t('workflowWebhookAction.addParameter')}\n removeItemLabel={(index) =>\n t('workflowWebhookAction.removeParameter', {\n number: index + 1,\n })\n }\n onAdd={addRow}\n onRemove={removeRow}\n renderItem={(row, index) => (\n <div\n data-parameter-id={row.key}\n className={parameterRowVariants()}\n >\n <FormField\n label={t('workflowWebhookAction.parameterName')}\n error={rowError(row.key)}\n announceError={announceErrors}\n >\n <TextInput\n ref={(node) => {\n if (node) nameInputs.current.set(row.key, node);\n }}\n aria-label={t(\n 'workflowWebhookAction.parameterNameOf',\n { number: index + 1 },\n )}\n dir=\"auto\"\n autoComplete=\"off\"\n spellCheck={false}\n value={row.name}\n onChange={(event) =>\n updateRow(row.key, { name: event.target.value })\n }\n onBlur={() => leave(`parameter:${row.key}`)}\n />\n </FormField>\n <FormField\n label={t('workflowWebhookAction.parameterValue')}\n >\n <TextInput\n ref={(node) => {\n if (node)\n valueInputs.current.set(row.key, node);\n }}\n aria-label={t(\n 'workflowWebhookAction.parameterValueOf',\n { number: index + 1 },\n )}\n dir=\"auto\"\n autoComplete=\"off\"\n value={row.value}\n onChange={(event) =>\n updateRow(row.key, {\n value: event.target.value,\n })\n }\n onFocus={() => visitedValues.current.add(row.key)}\n />\n </FormField>\n {variables.length > 0 ? (\n <div className=\"ds:sm:col-span-2\">\n <TokenInsertMenu\n tokens={variables.map((item) => ({\n value: item.value,\n label: item.label,\n }))}\n triggerLabel={t(\n 'workflowWebhookAction.insertDetail',\n )}\n onInsert={(token) =>\n insertPlaceholder(row, token)\n }\n />\n </div>\n ) : null}\n </div>\n )}\n />\n\n {variables.length > 0 ? (\n <div className={referenceSectionVariants()}>\n <h4\n id={variablesLabelId}\n className={sectionHeadingVariants()}\n >\n {t('workflowWebhookAction.variablesHeading')}\n </h4>\n <p className={helpVariants()}>\n {t('workflowWebhookAction.variablesDescription')}\n </p>\n {renderFields(\n variablesLabelId,\n variables.map(\n (item) => [item.value, item.label] as const,\n ),\n 3,\n )}\n </div>\n ) : null}\n </div>\n </Accordion.Content>\n </Accordion.Item>\n </Accordion>\n </Card>\n </div>\n\n {/* A card of its own: for whoever sets up the receiving app, so\n closed until asked for. */}\n <div data-slot=\"reference\">\n <Card variant=\"elevated\">\n <Accordion type=\"single\" collapsible>\n <Accordion.Item value=\"reference\">\n <Accordion.Trigger data-action=\"toggle-reference\">\n <span>{t('workflowWebhookAction.sentHeading')}</span>\n </Accordion.Trigger>\n <Accordion.Content>{reference}</Accordion.Content>\n </Accordion.Item>\n </Accordion>\n </Card>\n </div>\n\n {/* Generating, copying and inserting change what is on screen\n without a focus change a screen reader would notice. */}\n <span\n ref={liveRegion}\n role=\"status\"\n aria-live=\"polite\"\n className=\"ds:sr-only\"\n >\n {announcement}\n </span>\n </div>\n );\n },\n);\nWorkflowWebhookAction.displayName = 'WorkflowWebhookAction';\n"],"names":["__iconNode","KeyRound","createLucideIcon","WORKFLOW_WEBHOOK_ACTION_FIELDS","rootVariants","cva","fieldsGridVariants","referenceSectionVariants","sectionHeadingVariants","fieldNameVariants","helpVariants","errorVariants","parameterRowVariants","HTTPS","URL_MAX_LENGTH","TWO_COLUMN_MIN_WIDTH","PLATFORM_VARIABLES","EXAMPLE_IDEMPOTENCY_KEY","EXAMPLE_BODY","EXAMPLE_HEADERS","textOf","value","isUntouched","row","parameterEntries","rows","parametersJsonOf","entries","name","generateSecret","bytes","byte","firstServerMessage","errors","SentField","description","onCopied","t","useTranslation","descriptionId","useId","status","copy","useCopyToClipboard","copied","failed","jsxs","jsx","IconButton","Check","CircleAlert","Copy","WorkflowWebhookAction","forwardRef","children","initialValues","hasSavedSecret","fieldNames","placeholders","onSendTest","onValueChange","layout","className","rest","ref","sentFields","sentHeaders","legalErrorId","bodyLabelId","headersLabelId","variablesLabelId","testHelpId","variables","keyCounter","useRef","nextKey","url","setUrl","useState","secret","setSecret","generated","setGenerated","setRows","legal","setLegal","advancedOpen","setAdvancedOpen","touched","setTouched","submitted","setSubmitted","serverErrors","setServerErrors","announcement","setAnnouncement","testChecked","setTestChecked","answered","setAnswered","lastErrors","useEffect","setFocusRequest","leave","field","previous","forget","rootRef","urlInput","secretInput","copyButton","parametersError","legalBox","liveRegion","nameInputs","valueInputs","visitedValues","pendingCaret","pending","_a","fitsTwoColumns","setFitsTwoColumns","useIsomorphicLayoutEffect","node","measure","observer","twoColumns","setRootRef","useCallback","announce","message","frames","speak","urlProblem","parsed","secretProblem","rowProblems","problems","counts","legalProblem","due","rowsWithProblems","urlError","secretError","legalError","rowError","key","announceErrors","firstProblem","candidate","firstProblemRef","focusRequest","target","form","onSubmit","event","first","parametersJson","onValueChangeRef","entriesRef","mounted","copyStatus","copiedValue","resetCopy","secretCopied","secretCopyFailed","generateNewSecret","test","setTest","testRun","sendTest","problem","run","result","finishTest","next","outcome","describeTest","testedText","lastTestedText","state","ok","copySecret","updateRow","patch","addRow","removeRow","index","_","position","removed","neighbour","insertPlaceholder","token","input","visited","start","end","label","item","announceCopy","renderFields","labelId","items","wideColumns","exampleBody","reference","CodeBlock","native","secretDescription","FormField","TextInput","PasswordInput","Button","Send","Alert","Checkbox","Card","Accordion","Badge","FieldArray","TokenInsertMenu"],"mappings":"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","x_google_ignoreList":[0]}
|