import { type HTMLAttributes, type ReactNode } from 'react';
import { type UsePasswordRequirementsOptions } from '../../components/password-input';
import { type SelectOption } from '../../components/select';
import { type BrandMarkMotion } from '../_shared/brand-mark';
import { type RegistrationFieldVerification, type RegistrationVerifiableField } from './use-contact-verification';
/** The fields of the form, in the order they appear. */
export declare const REGISTRATION_FORM_FIELDS: readonly ["firstName", "lastName", "email", "emailConfirm", "password", "passwordConfirm", "phone", "branch", "terms"];
export type RegistrationFormField = (typeof REGISTRATION_FORM_FIELDS)[number];
/** The fields built on `TextInput`, which can refuse paste or copy. */
export type RegistrationFormTextField = Extract;
/** What `onSubmit` receives once every check has passed. A field the
* form does not show is empty (`''`, or `false` for the terms). */
export interface RegistrationFormValues {
firstName: string;
lastName: string;
email: string;
/** As typed. It matches `email` apart from case and outer spaces. */
emailConfirm: string;
password: string;
/** Equal to `password` when the confirm field is shown. */
passwordConfirm: string;
/** In E.164 form, e.g. `+393331234567`. */
phone: string;
/** The chosen `branches` value. */
branch: string;
/** True when the terms are shown: the form does not submit without. */
terms: boolean;
/** The reCAPTCHA token, when the host passes `recaptchaSiteKey`. */
captchaToken?: string;
}
/** Values to show when the form opens. There is no password here, on
* purpose: a password is never sent back to the browser. */
export type RegistrationFormInitialValues = Partial>;
/**
* What the development shortcut puts in the fields. Unlike
* `initialValues` it may carry a password: the host passes it only in
* development, from its own server, and the kit holds no test data of
* its own.
*/
export type RegistrationFormDevValues = Partial>;
/** The development-only shortcut at the top right of the card. */
export interface RegistrationFormDevBypass {
/** What the shortcut does: the button's name and tooltip. */
label: string;
/**
* The values to put in the fields when the button is pressed, as if
* typed: the checks, the password checklist and the posted values all
* see them. The confirm fields are filled from the same values, so
* they match. A field the form does not show is ignored, and a
* read-only email is kept.
*/
values?: RegistrationFormDevValues;
/**
* True to submit the form right after filling it, through the normal
* path: the checks still run, reCAPTCHA still runs, a native form
* still posts. Default false: fill only.
*/
submit?: boolean;
/** Called after filling, for a host with a route of its own. */
onClick?: () => void;
}
/** Messages from the server, already translated by the host: one per
* field, plus `form` for a message about the whole form. */
export type RegistrationFormErrors = Partial>;
/** The data behind the existing-account state of `RegistrationForm`. */
export interface RegistrationFormExistingAccount {
/** Where "Sign in" goes. Same tab. An unsafe address is dropped. */
loginHref: string;
/** Where "Reset password" goes. Optional. Same tab. An unsafe address is dropped. */
resetPasswordHref?: string;
}
/** The host's own form field names, for a native form post. `captcha`
* names the hidden field that carries the reCAPTCHA token. */
export type RegistrationFormFieldNames = Partial>;
export interface RegistrationFormProps extends Omit, 'title' | 'onSubmit'> {
/** Replaces the heading "Create your account". Pass it translated. */
title?: string;
/** A line under the heading, e.g. "No installation needed". Pass it
* translated. */
description?: string;
/** The heading's level. Default 2, for a page that has its own `h1`. */
headingLevel?: 1 | 2 | 3;
/**
* Shows the Alfadocs mark above the heading, with the heading and its
* line centred under it. Default true. With `false` the heading sits
* at the start edge, for a host that shows its own logo beside the
* card.
*/
showLogo?: boolean;
/**
* How the mark arrives when the card opens: its pieces come together
* (`assemble`, the default), it turns once (`spin`), it beats
* (`pulse`), or it is still (`none`). It plays once and rests, and
* holds still under reduced motion and in the accessible themes.
*/
logoMotion?: BrandMarkMotion;
/**
* Host content between the heading and the fields, such as a notice
* or a list of benefits. It sits outside the form, so nothing in it is
* posted. Keep any heading inside it below the card's own level.
*/
children?: ReactNode;
/**
* A short notice above the fields, as plain text already translated. It
* shows as an info alert, quiet to screen readers (it is not news). For
* a server-rendered page that can only pass JSON. Comes before
* `benefits` and `children`.
*/
notice?: string;
/**
* What the person gets, one short line each, already translated. They
* show as a compact list with a tick. Comes after `notice` and before
* `children`.
*/
benefits?: string[];
/**
* The fields to show. Default: all of them, which is the doctor form.
* A patient form is `['email', 'password', 'passwordConfirm', 'terms']`.
* Leave out `emailConfirm` or `passwordConfirm` to drop that confirm
* field. The list picks fields, it does not order them; email and
* password always show; `branch` also needs `branches`.
*/
fields?: readonly RegistrationFormField[];
/** Values to show when the form opens, such as the email from an
* invite link. Read once. Never a password. */
initialValues?: RegistrationFormInitialValues;
/**
* Messages from the server, already translated. Each shows on its
* field until the user changes that field; `form` shows above the
* fields, as does a message for a field the form does not show.
*
* Messages present when the form opens (a page the server rendered
* after a failed post) take focus: the error summary at the top of the
* form, which lists each field with a message, or the message above the
* fields when no field has one.
*
* On a React host, when the messages change, both password fields
* are emptied and focus moves as above. Set `submitting` while you
* send: the form then also notices an answer that says the same as
* the last one (another address, also taken), which the messages
* alone cannot show. Any object works, kept in state or rebuilt on
* each render (`errors={{ email: emailError }}`).
*/
errors?: RegistrationFormErrors;
/**
* Shows the email from `initialValues` read-only, for a person invited
* with an address they cannot change here. Off by default: choose it
* only when the server will refuse any other address. The value is
* still posted and still read out, there is no confirm email field,
* and the browser does not check it. Ignored when there is no initial
* email, so the field is never both empty and locked.
*/
emailReadOnly?: boolean;
/** A line under the email field, e.g. "You can change it later in the
* settings". Pass it translated. */
emailDescription?: string;
/**
* Fields that refuse paste and drop, so the user types them, e.g.
* `['passwordConfirm']`. Default: none. Autofill from the browser or a
* password manager still works. A refused paste is announced and shown
* under the field. The host decides: see the docs for the WCAG
* position, which differs between the email and password fields.
*/
blockPaste?: readonly RegistrationFormTextField[];
/**
* Fields that refuse copy, cut and dragging text out. Default: none.
* Browsers already refuse to copy from a password field while it is
* hidden. See the docs for the WCAG position.
*/
blockCopy?: readonly RegistrationFormTextField[];
/** The specialities to choose from. The field shows, and is required,
* only when this has entries. */
branches?: SelectOption[];
/**
* The password rules, shown as a live checklist. Keep them equal to
* the server's. Default: 12 characters with an uppercase letter, a
* lowercase letter and a number, counting only `A-Z`, `a-z` and `0-9`
* (`charset: 'ascii'`), which is the platform's rule.
*/
passwordPolicy?: UsePasswordRequirementsOptions;
/**
* Where "terms of use" leads. A path on the same site, or an address
* written in full (`https://…`). Anything else, such as an address
* that would lead off the site without saying so, shows the words
* without a link.
*/
termsHref?: string;
/** Where "privacy policy" leads. Same rule as `termsHref`. */
privacyHref?: string;
/**
* Replaces the sentence beside the terms box ("I accept the terms of
* use and the privacy policy") with the host's own wording and links,
* already translated. The legal wording is the host's to choose. When
* set, `termsHref` and `privacyHref` are not used. The box stays
* required.
*/
termsLabel?: ReactNode;
/**
* `termsLabel` as a string, for a host that can only pass JSON. Already
* translated. Mark the links with `…` and
* `…`: they lead to `termsHref` and `privacyHref`
* (new tab; without a safe address, the words show without a link).
* Any other tag shows its text only. No marker: plain text. Ignored
* when `termsLabel` is set.
*/
termsLabelText?: string;
/** A line shown with the terms box and read out with it, e.g. "We
* will not send you any advertising". Pass it translated. */
termsDescription?: ReactNode;
/** `termsDescription` as a string, with the same markers as
* `termsLabelText`. Ignored when `termsDescription` is set. */
termsDescriptionText?: string;
/** Adds "Already have an account? Sign in". Same rule as `termsHref`. */
loginHref?: string;
/**
* The server refused the email because an account already has it. The email
* field shows the kit's own message, naming the way forward, with a link to
* sign in and a link to reset the password. Data only, so it works from JSON.
*
* The state is read against the email the form opened with
* (`initialValues.email`, which must not be empty), so it is for a page the
* server renders again after refusing the post. A React host that answers
* through `onSubmit` mounts the form again (a new `key`) with
* `initialValues.email` set to the refused address. Any edit to the email
* removes the message and the links; typing the opening address back brings
* them back. While it shows, the card's footer sign-in line is hidden, so
* there is one "Sign in".
*
* Privacy: an address in a link's URL lands in server logs and in analytics
* page URLs. Preferred: keep the address in the host's own session and link
* plainly (`/login`). Allowed: put it in the query string
* (`/login?email=...`).
*/
existingAccount?: RegistrationFormExistingAccount;
/** A Google reCAPTCHA v2 site key of the invisible type. The check
* runs when the user submits. Leave it out where the server does not
* verify a token. */
recaptchaSiteKey?: string;
/** Replaces the button's "Create account". Pass it translated. */
submitLabel?: string;
/** True while the host sends the values: the button shows a spinner
* and a second submit is ignored. */
submitting?: boolean;
/**
* Shows the development-only shortcut button at the top right of the
* card: it fills the form with the host's `values`, and submits it
* when asked to. Pass it only when the server says this is a
* development environment: the kit never decides that itself, holds
* no test data, and what the shortcut submits goes through the normal
* path, so the server's own rules still decide. With neither `values`
* nor `onClick` there is nothing to do and no button.
*/
devBypass?: RegistrationFormDevBypass;
/** For React hosts: called with the values once every check has
* passed. Not called when `fieldNames` is set. */
onSubmit?: (values: RegistrationFormValues) => void;
/**
* For a native form post: the host's own field names, e.g.
* `{ email: 'registration[email]' }`. When set, the inputs carry
* these names and the browser posts the form. A field without a name
* here is not posted: name a confirm field only if the server's form
* has one, or it may refuse the post as carrying extra fields.
*/
fieldNames?: RegistrationFormFieldNames;
/**
* Where a native form post goes. Default: the current address, query
* string included, which is what a page reached through an invite link
* needs. Only an address on this site is accepted: another site is
* never sent what the user typed, and the post then goes to the
* current address instead.
*/
action?: string;
/**
* Extra hidden inputs posted with a native form, by name: a CSRF token
* or similar. Not used with `onSubmit`. A name that is also one of
* `fieldNames` is left out: the form's own field wins.
*/
hiddenFields?: Readonly>;
/**
* Proves an email or a phone number with a code before the form
* submits. For each field named here the card shows "Send code" beside
* the field, a code box once a code is out, and locks the field
* (read-only, still posted) when the code is right. The host sends and
* checks the codes on its server, which must also refuse the form when
* the value was not verified: this is a convenience for the person,
* not the check. Without it the form is unchanged.
*
* `Confirm email` stays; leave `emailConfirm` out of `fields` to drop it.
*/
verification?: Partial>;
/**
* With `verification`, the form does not submit until every field named
* there is verified. Default true.
*/
requireVerification?: boolean;
}
/**
* The registration form card, for doctors and for patients. The host
* picks the fields, supplies the page around the card and owns every
* server rule; see the props for the two ways to submit. The card's
* text follows the kit's language, like every kit component.
*/
export declare const RegistrationForm: import("react").ForwardRefExoticComponent>;
//# sourceMappingURL=registration-form.d.ts.map