@alfadocs/ui-kit-debug 1.78.0 → 1.80.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-By4I_1A-.js} +1766 -1749
- package/dist/_chunks/booking-By4I_1A-.js.map +1 -0
- 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/{practice-results-BnY2EkzI.js → practice-results-CtOanuzZ.js} +659 -615
- package/dist/_chunks/practice-results-CtOanuzZ.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 +91 -5
- 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/booking-types.d.ts +16 -1
- package/dist/components/booking/booking-types.d.ts.map +1 -1
- package/dist/components/booking/booking.d.ts.map +1 -1
- package/dist/components/booking/cascade.d.ts +3 -0
- package/dist/components/booking/cascade.d.ts.map +1 -1
- package/dist/components/booking/details-form.d.ts +2 -0
- package/dist/components/booking/details-form.d.ts.map +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/practice-results/index.js +1 -1
- package/dist/components/practice-results/practice-results.d.ts +19 -2
- package/dist/components/practice-results/practice-results.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 +28 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +30 -2
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +28 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +30 -2
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +28 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +30 -2
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +28 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +29 -1
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +28 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +30 -2
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +28 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +30 -2
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +28 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +30 -2
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +28 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +30 -2
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +28 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +30 -2
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +28 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +30 -2
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +28 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +30 -2
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +28 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +30 -2
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +28 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +30 -2
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +28 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +30 -2
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +28 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +30 -2
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +28 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +30 -2
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +28 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +30 -2
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +28 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +30 -2
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +90 -87
- package/dist/index.js.map +1 -1
- package/dist/locales/ar.json +30 -2
- package/dist/locales/de.json +30 -2
- package/dist/locales/el.json +30 -2
- package/dist/locales/en.json +29 -1
- package/dist/locales/es.json +30 -2
- package/dist/locales/fr.json +30 -2
- package/dist/locales/hi.json +30 -2
- package/dist/locales/it.json +30 -2
- package/dist/locales/ja.json +30 -2
- package/dist/locales/nl.json +30 -2
- package/dist/locales/pl.json +30 -2
- package/dist/locales/pt.json +30 -2
- package/dist/locales/ro.json +30 -2
- package/dist/locales/ru.json +30 -2
- package/dist/locales/sq.json +30 -2
- package/dist/locales/sv.json +30 -2
- package/dist/locales/tr.json +30 -2
- package/dist/locales/zh.json +30 -2
- 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/dist/tokens.css +1 -1
- package/package.json +5 -1
- package/dist/_chunks/booking-Cz_QjIJe.js.map +0 -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/practice-results-BnY2EkzI.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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registration-form-CNBfUduG.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, KeyRound, LogIn } 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 data behind the existing-account state of `RegistrationForm`. */\nexport interface RegistrationFormExistingAccount {\n /** Where \"Sign in\" goes. Same tab. An unsafe address is dropped. */\n loginHref: string;\n /** Where \"Reset password\" goes. Optional. Same tab. An unsafe address is dropped. */\n resetPasswordHref?: 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 /**\n * The server refused the email because an account already has it. The email\n * field shows the kit's own message, naming the way forward, with a link to\n * sign in and a link to reset the password. Data only, so it works from JSON.\n *\n * The state is read against the email the form opened with\n * (`initialValues.email`, which must not be empty), so it is for a page the\n * server renders again after refusing the post. A React host that answers\n * through `onSubmit` mounts the form again (a new `key`) with\n * `initialValues.email` set to the refused address. Any edit to the email\n * removes the message and the links; typing the opening address back brings\n * them back. While it shows, the card's footer sign-in line is hidden, so\n * there is one \"Sign in\".\n *\n * Privacy: an address in a link's URL lands in server logs and in analytics\n * page URLs. Preferred: keep the address in the host's own session and link\n * plainly (`/login`). Allowed: put it in the query string\n * (`/login?email=...`).\n */\n existingAccount?: RegistrationFormExistingAccount;\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 existingAccount,\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 // The kit's own message, while the email is the one the server refused.\n const [openedEmail] = useState(() => initialValues?.email ?? '');\n const existingNow =\n Boolean(existingAccount) && hadEmail && values.email === openedEmail;\n const existingSignIn = linkTo(existingAccount?.loginHref);\n const existingReset = linkTo(existingAccount?.resetPasswordHref);\n const existingMessage = t(\n existingSignIn && existingReset\n ? 'registrationForm.existingAccount.messageSignInOrReset'\n : existingSignIn\n ? 'registrationForm.existingAccount.messageSignIn'\n : existingReset\n ? 'registrationForm.existingAccount.messageReset'\n : 'registrationForm.existingAccount.message',\n );\n const errorFor = (field: RegistrationFormField) =>\n field === 'email' && existingNow\n ? existingMessage\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 // `existingAccount` is a server answer too, with or without `errors.email`.\n const [openedWithFieldMessage] = useState(\n () =>\n shown.some((field) => Boolean(errors?.[field])) ||\n (Boolean(existingAccount) && hadEmail),\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 const existingActions =\n existingNow && (existingSignIn || existingReset) ? (\n <>\n {existingSignIn && (\n <Button\n asChild\n intent=\"secondary\"\n startIcon={<LogIn />}\n data-action=\"sign-in\"\n >\n <a href={existingSignIn}>{t('loginForm.submit')}</a>\n </Button>\n )}\n {existingReset && (\n <Button\n asChild\n intent=\"secondary\"\n startIcon={<KeyRound />}\n data-action=\"reset-password\"\n >\n <a href={existingReset}>{t('loginForm.forgot')}</a>\n </Button>\n )}\n </>\n ) : undefined;\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 errorAction={existingActions}\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 && !existingNow && (\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","existingAccount","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","openedEmail","existingNow","existingSignIn","existingReset","existingMessage","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","existingActions","LogIn","KeyRound","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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"}
|