@alfadocs/ui-kit-debug 1.70.0 → 1.71.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login-dev-card-CWpoTuVY.js","sources":["../../src/patterns/login-form/login-form.tsx","../../src/patterns/login-form/login-dev-card.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* LoginForm — the sign-in card. */\n/* */\n/* One export for the card: the mark, the heading, email and password, */\n/* the way to a new password, the button and the ways to register. The */\n/* host keeps the page around it and every server rule. The card checks */\n/* what a browser can check, then hands the values to `onSubmit` or */\n/* posts a real form to the host's own field names. */\n/* */\n/* The email must be an email address. A server that also signs people */\n/* in by a username cannot use this card for those accounts. */\n/* -------------------------------------------------------------------- */\n\nimport {\n forwardRef,\n useEffect,\n useId,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { cva } from 'class-variance-authority';\n// The validator EmailInput itself uses, so the two never disagree.\nimport isEmail from 'validator/lib/isEmail';\nimport { Button } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { EmailInput } from '../../components/email-input';\nimport { ErrorSummary } from '../../components/error-summary';\nimport { FormField } from '../../components/form-field';\nimport { PasswordInput } from '../../components/password-input';\nimport { isSafeHref } from '../../components/_shared/safe-href';\nimport { useStateBackedInput } from '../../components/_shared/use-state-backed-input';\nimport {\n AuthCardHeading,\n AuthFormMessage,\n AuthFormStatus,\n AuthTextLink,\n ExtraFields,\n useExtraFields,\n useFormAction,\n} from '../_shared/auth-form-parts';\nimport type { BrandMarkMotion } from '../_shared/brand-mark';\nimport {\n useErrorSummary,\n useFormMessageAnnounce,\n} from '../_shared/use-error-summary';\nimport { useRegistrationSubmit } from '../registration-form/use-registration-submit';\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** The fields of the form, in the order they appear. */\nexport const LOGIN_FORM_FIELDS = ['email', 'password'] as const;\n\nexport type LoginFormField = (typeof LOGIN_FORM_FIELDS)[number];\n\n/** What `onSubmit` receives once both checks have passed. */\nexport interface LoginFormValues {\n email: string;\n password: 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 LoginFormInitialValues = Partial<Pick<LoginFormValues, 'email'>>;\n\n/** Messages from the server, already translated: one per field, plus\n * `form` for a message about the whole form, such as \"the email or\n * password is incorrect\". */\nexport type LoginFormErrors = Partial<Record<LoginFormField | 'form', string>>;\n\n/** The host's own form field names, for a native form post. Both are\n * needed: a field without a name is not posted. */\nexport type LoginFormFieldNames = Record<LoginFormField, string>;\n\nexport interface LoginFormProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'title' | 'onSubmit'\n> {\n /** Replaces the heading \"Sign in to Alfadocs\". Pass it translated. */\n title?: string;\n /** A line under the heading. Pass it translated. */\n description?: string;\n /**\n * The heading's level. Default 1: a sign-in page usually has no other\n * heading. Pass 2 on a page that has its own `h1`.\n */\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.\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 * (\"You have been signed out\"). It sits outside the form, so nothing in\n * it is posted. Keep any heading inside it below the card's own level.\n */\n children?: ReactNode;\n /** The email to show when the form opens, such as the one last used.\n * Read once. There is never an initial password. */\n initialValues?: LoginFormInitialValues;\n /**\n * Messages from the server, already translated. A field's message\n * shows on that field until the user changes it; `form` shows above\n * the fields.\n *\n * When messages arrive, the password is emptied and focus moves: to\n * the error summary at the top of the form, which lists each field\n * with a message, or, when only `form` says something, to the\n * password, which is then described by that message. The same happens\n * for messages present when the form opens (a page the server rendered\n * after a failed post).\n *\n * Never say which of the two values was wrong: one message for both.\n * Set `submitting` while you send, so the form also notices an answer\n * that says the same as the last one.\n */\n errors?: LoginFormErrors;\n /**\n * Adds \"Forgot password?\" under the password. A path on the same site,\n * or an address written in full (`https://…`). Anything else shows no\n * link. The same rule holds for the two addresses below.\n */\n forgotPasswordHref?: string;\n /** Adds \"Register as a doctor\" under the button. */\n registerDoctorHref?: string;\n /** Adds \"Register as a patient\" under the button. */\n registerPatientHref?: string;\n /** Replaces the button's \"Sign in\". Pass it translated. */\n submitLabel?: string;\n /**\n * True while the host sends the values: the button shows a spinner and\n * a second submit is ignored. Set it inside `onSubmit`, before anything\n * is awaited: until it is true, a second press sends a second sign-in.\n */\n submitting?: boolean;\n /** For React hosts: called with the values once both checks have\n * passed. Not called when `fieldNames` is set. */\n onSubmit?: (values: LoginFormValues) => void;\n /**\n * For a native form post: the host's own field names, both of them,\n * e.g. `{ email: 'email', password: 'password' }`. When set, the inputs\n * carry these names and the browser posts the form.\n */\n fieldNames?: LoginFormFieldNames;\n /**\n * Where a native form post goes. Default: the current address. Only a\n * path, or an address on the page's own origin, is accepted: another\n * origin is never sent what the user typed, and the post then goes to\n * the current address. Does nothing without `fieldNames`.\n */\n action?: string;\n /**\n * Extra hidden inputs posted with a native form, by name: a CSRF token,\n * a return address. Not used with `onSubmit`. A name that is also one\n * of `fieldNames` is left out: the form's own field wins. The server\n * must check a return address itself: anyone can change a hidden input.\n */\n hiddenFields?: Readonly<Record<string, string>>;\n /**\n * A second card beside the sign-in, the same height: the development\n * quick sign-in (`LoginDevCard`). Pass it only when the server says\n * this is a development environment: the kit never decides that\n * itself. The two sit side by side where there is room and stack on a\n * phone.\n */\n devCard?: ReactNode;\n}\n\n/* -------------------------------------------------------------------- */\n/* Styles */\n/* -------------------------------------------------------------------- */\n\n// The card is 400px wide at most, written in px: a host whose root font\n// size is not 16px would stretch or squeeze a width in rem.\nconst loginFormVariants = cva(\n 'ds:flex ds:w-full ds:flex-col ds:items-center ds:justify-center ds:gap-[var(--spacing-lg)] ds:text-start ds:text-[var(--foreground)] ds:lg:flex-row ds:lg:items-stretch',\n);\n\nconst columnVariants = cva('ds:w-full ds:max-w-[400px]');\n\n// The two ways to register, side by side where they fit. The row gap\n// keeps the links' 44px touch targets apart when they wrap.\nconst registerLinksVariants = cva(\n 'ds:flex ds:flex-wrap ds:justify-center ds:gap-x-[var(--spacing-lg)] ds:gap-y-[var(--spacing-lg)]',\n);\n\n/* -------------------------------------------------------------------- */\n/* Helpers */\n/* -------------------------------------------------------------------- */\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: LoginFormErrors): boolean =>\n Object.values(errors).some(Boolean);\n\nconst hasFieldMessage = (errors: LoginFormErrors): boolean =>\n LOGIN_FORM_FIELDS.some((field) => Boolean(errors[field]));\n\n/**\n * Where to send the user for a set of server messages: the first field\n * that has one. A message about the whole form sends them to the\n * password, the field they will have to type again.\n */\nconst focusTargetFor = (\n messages: LoginFormErrors,\n): LoginFormField | undefined =>\n LOGIN_FORM_FIELDS.find((field) => messages[field]) ??\n (messages.form ? 'password' : undefined);\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\n/**\n * The sign-in card. Mount it on the login page, inside `SignedOutFrame`\n * or the host's own chrome.\n */\nexport const LoginForm = forwardRef<HTMLDivElement, LoginFormProps>(\n (\n {\n title,\n description,\n headingLevel = 1,\n showLogo = true,\n logoMotion = 'assemble',\n children,\n initialValues,\n errors,\n forgotPasswordHref,\n registerDoctorHref,\n registerPatientHref,\n submitLabel,\n submitting = false,\n onSubmit,\n fieldNames,\n action,\n hiddenFields,\n devCard,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const titleId = useId();\n const formMessageId = useId();\n const fieldIdBase = useId();\n /** The id of a field's wrapper: where the summary's link leads. */\n const fieldId = (field: LoginFormField) => `${fieldIdBase}-${field}`;\n const native = fieldNames !== undefined;\n\n /* ------------------------------ State ----------------------------- */\n\n // Read once. The password always starts empty.\n const [email, setEmail] = useState(() => initialValues?.email ?? '');\n const [password, setPassword] = useState('');\n // A field the user has filled in and left. An email that arrives\n // filled in counts: a bad one is then flagged at once, with its\n // message. An empty field is not flagged for being passed through: a\n // keyboard user on the way to \"Forgot password?\" has made no mistake.\n // Its message waits for a submit.\n const [touched, setTouched] = useState<\n Partial<Record<LoginFormField, boolean>>\n >(() => ({ email: Boolean(initialValues?.email) }));\n const [submitted, setSubmitted] = useState(false);\n const [serverErrors, setServerErrors] = useState<LoginFormErrors>(\n () => errors ?? {},\n );\n\n const leave = (field: LoginFormField) =>\n setTouched((previous) =>\n previous[field] ? previous : { ...previous, [field]: true },\n );\n // The server's message was about the old value.\n const forget = (field: LoginFormField) =>\n setServerErrors((previous) =>\n previous[field] ? { ...previous, [field]: undefined } : previous,\n );\n\n const emailInput = useRef<HTMLInputElement>(null);\n const passwordInput = useRef<HTMLInputElement>(null);\n // The address stays out of the input's `value` attribute, where a\n // copied outerHTML or a session replay could read it.\n const emailField = useStateBackedInput(email, emailInput);\n\n const emptyPassword = () => {\n setPassword('');\n setTouched((previous) => ({ ...previous, password: false }));\n };\n /**\n * What the two inputs hold now. Read from the inputs, not from state:\n * a browser or a password manager can fill a field without telling\n * React, and the form must not refuse a field that is visibly filled.\n */\n const held = (): LoginFormValues => {\n const values = {\n email: emailInput.current?.value ?? email,\n password: passwordInput.current?.value ?? password,\n };\n if (values.email !== email) setEmail(values.email);\n if (values.password !== password) setPassword(values.password);\n return values;\n };\n\n /* ---------------------------- Validation -------------------------- */\n\n /** What stops a submit, whether or not the message shows yet. The\n * password only has to be there: its rules are for a new password. */\n const invalid: Record<LoginFormField, boolean> = {\n email: !isEmail(email),\n password: password === '',\n };\n // A message shows once the user has filled in and left the field, or\n // tried to submit.\n const due = (field: LoginFormField) => submitted || touched[field] === true;\n const ownErrors: Record<LoginFormField, string | undefined> = {\n email:\n due('email') && invalid.email\n ? email === ''\n ? t('loginForm.emailRequired')\n : t('inputs.email.invalid')\n : undefined,\n password:\n due('password') && invalid.password\n ? t('loginForm.passwordRequired')\n : undefined,\n };\n const errorFor = (field: LoginFormField) =>\n serverErrors[field] ?? ownErrors[field];\n\n /* ------------------------------ Focus ----------------------------- */\n\n // Every field with a message after a refused submit, or after a server\n // answer, is listed at the top of the form, and focus goes there. A\n // page the server rendered after a failed post opens that way too: it\n // announces nothing itself.\n const [openedWithFieldMessage] = useState(() =>\n hasFieldMessage(errors ?? {}),\n );\n const summary = useErrorSummary(\n LOGIN_FORM_FIELDS,\n errorFor,\n openedWithFieldMessage,\n );\n\n // Any other place focus goes: the password, when only the message\n // about the whole form says something. A new object for each request,\n // so asking twice for the same place moves focus twice. The effect runs\n // after the messages are drawn, so a screen reader lands on something\n // that already says what is wrong.\n const [focusRequest, setFocusRequest] = useState<{\n target: LoginFormField;\n } | null>(() => {\n const target = openedWithFieldMessage\n ? undefined\n : focusTargetFor(errors ?? {});\n return target ? { target } : null;\n });\n useEffect(() => {\n if (!focusRequest) return;\n (focusRequest.target === 'email'\n ? emailInput\n : passwordInput\n ).current?.focus();\n }, [focusRequest]);\n\n /* ------------------------------ Submit ---------------------------- */\n\n const submit = useRegistrationSubmit<LoginFormField>({\n errors,\n submitting,\n native,\n captcha: false,\n firstProblem: () => {\n const values = held();\n if (!isEmail(values.email)) return 'email';\n return values.password === '' ? 'password' : undefined;\n },\n onRefused: (field) => {\n // Both messages now show, listed in the summary, which takes focus.\n setSubmitted(true);\n summary.open(() => setFocusRequest({ target: field }));\n },\n // Only a React host gets here: a native post is the browser's own.\n deliver: () => onSubmit?.(held()),\n onAnswer: (answer) => {\n const next: LoginFormErrors = answer;\n setServerErrors(next);\n if (!hasMessage(next)) return;\n // Never keep a password the server did not accept.\n emptyPassword();\n setSubmitted(false);\n // The summary when a field has a message, else the password.\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: the\n // password must not come back with it.\n onRestore: emptyPassword,\n });\n const { busy } = submit;\n\n /* ------------------------------ Render ---------------------------- */\n\n const formAction = useFormAction('LoginForm', native, action);\n const forgotLink = linkTo(forgotPasswordHref);\n const doctorLink = linkTo(registerDoctorHref);\n const patientLink = linkTo(registerPatientHref);\n const extraFields = useExtraFields(\n 'LoginForm',\n native,\n fieldNames,\n hiddenFields,\n );\n const formError = serverErrors.form;\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\n return (\n <div\n ref={ref}\n {...rest}\n data-component=\"login-form\"\n className={loginFormVariants({ className })}\n >\n <div className={columnVariants()}>\n <Card variant=\"elevated\" className=\"ds:h-full\">\n <Card.Body className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-lg)]\">\n <AuthCardHeading\n id={titleId}\n title={title ?? t('loginForm.title')}\n description={description}\n level={headingLevel}\n showLogo={showLogo}\n logoMotion={logoMotion}\n />\n\n {children ? (\n <div\n data-slot=\"host-content\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\"\n >\n {children}\n </div>\n ) : null}\n\n {/* 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 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 field,\n message: errorFor(field) ?? '',\n targetId: fieldId(field),\n }))}\n />\n\n {formError && (\n <AuthFormMessage\n id={formMessageId}\n announce={formMessageAnnounce}\n >\n {formError}\n </AuthFormMessage>\n )}\n\n <FormField\n id={fieldId('email')}\n label={t('loginForm.email')}\n required\n error={errorFor('email')}\n // Quiet while the summary lists it: the summary reads it.\n announceError={!summary.lists('email')}\n data-field=\"email\"\n >\n {/* One check, above, drives the message, the red mark and\n aria-invalid through FormField. EmailInput's own check\n is off so the two cannot disagree. `username` is the\n name browsers and password managers give the field\n that goes with `current-password`. */}\n <EmailInput\n ref={emailField.ref}\n name={native ? fieldNames.email : 'email'}\n autoComplete=\"username\"\n disableBuiltInValidation\n onChange={emailField.quiet((event) => {\n setEmail(event.target.value);\n forget('email');\n })}\n onBlur={(event) => {\n // Whatever a browser filled in without saying so.\n setEmail(event.target.value);\n if (event.target.value !== '') leave('email');\n }}\n />\n </FormField>\n\n <FormField\n id={fieldId('password')}\n label={t('loginForm.password')}\n required\n error={errorFor('password')}\n announceError={!summary.lists('password')}\n data-field=\"password\"\n >\n {/* Described by the message above the fields when there is\n one: focus lands here after a refused sign-in, and a\n screen reader then reads why. */}\n <PasswordInput\n ref={passwordInput}\n name={native ? fieldNames.password : 'password'}\n autoComplete=\"current-password\"\n aria-describedby={formError ? formMessageId : undefined}\n value={password}\n onChange={(event) => {\n setPassword(event.target.value);\n forget('password');\n }}\n onBlur={(event) => {\n setPassword(event.target.value);\n if (event.target.value !== '') leave('password');\n }}\n />\n </FormField>\n\n {forgotLink && (\n <AuthTextLink\n href={forgotLink}\n action=\"forgot-password\"\n align=\"end\"\n >\n {t('loginForm.forgot')}\n </AuthTextLink>\n )}\n\n <ExtraFields fields={extraFields} />\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 >\n {submitLabel ?? t('loginForm.submit')}\n </Button>\n </form>\n\n {/* Outside the form: they lead to other pages and post\n nothing. The header's own labels, already translated. */}\n {(doctorLink || patientLink) && (\n <div\n data-slot=\"register-links\"\n className={registerLinksVariants()}\n >\n {doctorLink && (\n <AuthTextLink href={doctorLink} action=\"register-doctor\">\n {t('signedOutHeader.registerDoctor')}\n </AuthTextLink>\n )}\n {patientLink && (\n <AuthTextLink href={patientLink} action=\"register-patient\">\n {t('signedOutHeader.registerPatient')}\n </AuthTextLink>\n )}\n </div>\n )}\n {/* Outside the form: a screen reader may hold back what\n changes inside a busy region. */}\n <AuthFormStatus busy={busy} />\n </Card.Body>\n </Card>\n </div>\n {devCard ? <div className={columnVariants()}>{devCard}</div> : null}\n </div>\n );\n },\n);\nLoginForm.displayName = 'LoginForm';\n","/* -------------------------------------------------------------------- */\n/* LoginDevCard — the development quick sign-in card. */\n/* */\n/* A second card beside the login, for developers: one link per test */\n/* account the host's server can sign in. The kit only draws it. The */\n/* host decides whether it is rendered, supplies every word on it, and */\n/* its server must refuse the routes outside development. */\n/* -------------------------------------------------------------------- */\n\nimport { forwardRef, useId, type HTMLAttributes, type ReactNode } from 'react';\nimport { cva } from 'class-variance-authority';\nimport { Button } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { MatrixRain } from '../../components/matrix-rain';\nimport { isSafeHref } from '../../components/_shared/safe-href';\nimport { ErrorPageIllustration } from '../error-page/error-page-illustration';\n\nexport interface LoginDevOption {\n /** The link's text, e.g. \"Sign in as admin\". The host supplies it, so\n * the kit ships no text for a card that users never see. */\n label: string;\n /** The development-only route that signs the test account in. A path\n * on the same site, or an address written in full. */\n href: string;\n /** A Lucide icon for the link, passed bare: `<ShieldUser />`. */\n icon?: ReactNode;\n}\n\nexport interface LoginDevCardProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'title'\n> {\n /** The card's heading, e.g. \"Developer quick login\". */\n title: string;\n /** One link per test account. An option with an unsafe address is\n * left out. */\n options: readonly LoginDevOption[];\n /** The heading's level. Default 2, under the login's own heading. */\n headingLevel?: 2 | 3;\n}\n\n// As tall as the login beside it, so the two cards read as a pair.\nconst loginDevCardVariants = cva('ds:h-full ds:w-full');\n\n/**\n * The development quick sign-in card. Render it only when the server\n * says this is a development environment: it never checks the\n * environment itself. Pass it to `LoginForm` as `devCard`.\n */\nexport const LoginDevCard = forwardRef<HTMLDivElement, LoginDevCardProps>(\n ({ title, options, headingLevel = 2, className, ...rest }, ref) => {\n const titleId = useId();\n const Heading = `h${headingLevel}` as const;\n const links = options.filter((option) => isSafeHref(option.href));\n return (\n <div\n ref={ref}\n {...rest}\n data-component=\"login-dev-card\"\n className={loginDevCardVariants({ className })}\n >\n <Card\n variant=\"elevated\"\n aria-labelledby={titleId}\n className=\"ds:relative ds:isolate ds:flex ds:h-full ds:flex-col ds:overflow-hidden\"\n >\n {/* Code rain round the edges, clear in the middle so it never runs\n behind the links. MatrixRain holds still under reduced motion by\n itself; it does not know the accessible themes, so the rain is\n taken out there, like the kit's other decorative motion. */}\n <div className=\"ds:absolute ds:inset-0 ds:z-0 ds:[display:var(--accessible-off,block)]\">\n <MatrixRain\n glyphs=\"hex\"\n decay=\"fast\"\n mask=\"center\"\n maskRadius=\"xl\"\n className=\"ds:size-full\"\n />\n </div>\n <Card.Header className=\"ds:relative ds:z-[1]\">\n <div className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)] ds:text-center\">\n {/* The melting mark from the error pages, at half its size\n there. */}\n <div className=\"ds:[&>div]:w-24\">\n <ErrorPageIllustration mood=\"melt\" />\n </div>\n <Heading\n id={titleId}\n className=\"type-title-card ds:text-[var(--foreground)]\"\n >\n {title}\n </Heading>\n </div>\n </Card.Header>\n <Card.Body className=\"ds:relative ds:z-[1] ds:flex ds:flex-1 ds:flex-col ds:justify-center\">\n {/* The top margin keeps the heading clear of the links when the\n cards stack and this one is only as tall as its content. */}\n <div className=\"ds:mt-[var(--spacing-md)] ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]\">\n {links.map((option, index) => (\n <Button\n // Two options may share an address, so the place in the\n // list is part of the key.\n key={`${index}:${option.href}`}\n asChild\n intent=\"primary\"\n startIcon={option.icon}\n className=\"ds:min-h-[var(--min-target-size)] ds:w-full\"\n >\n <a href={option.href} data-action=\"dev-login\">\n {option.label}\n </a>\n </Button>\n ))}\n </div>\n </Card.Body>\n </Card>\n </div>\n );\n },\n);\nLoginDevCard.displayName = 'LoginDevCard';\n"],"names":["LOGIN_FORM_FIELDS","loginFormVariants","cva","columnVariants","registerLinksVariants","linkTo","href","isSafeHref","hasMessage","errors","hasFieldMessage","field","focusTargetFor","messages","LoginForm","forwardRef","title","description","headingLevel","showLogo","logoMotion","children","initialValues","forgotPasswordHref","registerDoctorHref","registerPatientHref","submitLabel","submitting","onSubmit","fieldNames","action","hiddenFields","devCard","className","rest","ref","useTranslation","titleId","useId","formMessageId","fieldIdBase","fieldId","native","email","setEmail","useState","password","setPassword","touched","setTouched","submitted","setSubmitted","serverErrors","setServerErrors","leave","previous","forget","emailInput","useRef","passwordInput","emailField","useStateBackedInput","emptyPassword","held","values","_a","_b","invalid","isEmail","due","ownErrors","errorFor","openedWithFieldMessage","summary","useErrorSummary","focusRequest","setFocusRequest","target","useEffect","submit","useRegistrationSubmit","answer","next","busy","formAction","useFormAction","forgotLink","doctorLink","patientLink","extraFields","useExtraFields","formError","formMessageAnnounce","useFormMessageAnnounce","jsxs","jsx","Card","AuthCardHeading","ErrorSummary","AuthFormMessage","FormField","EmailInput","event","PasswordInput","AuthTextLink","ExtraFields","Button","AuthFormStatus","loginDevCardVariants","LoginDevCard","options","Heading","links","option","MatrixRain","ErrorPageIllustration","index"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "packageVersion": "1.70.0",
3
+ "packageVersion": "1.71.0",
4
4
  "components": [
5
5
  {
6
6
  "kind": "component",
@@ -20259,6 +20259,14 @@
20259
20259
  "uiActions": [],
20260
20260
  "apiActions": []
20261
20261
  },
20262
+ {
20263
+ "name": "register",
20264
+ "safety": "read",
20265
+ "description": "Go to a registration page: `data-action=\"register-doctor\"` or `data-action=\"register-patient\"`, under the sign-in button. Each is present only when the host gives its address.",
20266
+ "descriptionKey": "ui.agent.loginForm.workflows.register",
20267
+ "uiActions": [],
20268
+ "apiActions": []
20269
+ },
20262
20270
  {
20263
20271
  "name": "dev_sign_in",
20264
20272
  "safety": "write",
@@ -1899,6 +1899,7 @@
1899
1899
  "readForm": "Read the sign-in form and what is wrong with it. Each field sits in a wrapper with `data-field` (`email`, `password`). A field with a problem has `aria-invalid=\"true\"` on its control and its message in a `data-slot=\"error\"` element inside the wrapper. After a refused submit the fields with a problem are also listed in `data-component=\"error-summary\"` at the top of the form, one item per field (`data-error-field`). A message about the whole form, such as a refused sign-in, is in `data-field=\"form\"`; it never says which of the two values was wrong. Never read or repeat the password.",
1900
1900
  "signIn": "Sign in (`data-action=\"submit\"`). The person types the email and the password themselves; the form does not submit until the email is a valid address and the password is not empty; it lists what is wrong in its error summary and moves focus there. The host then signs the person in: through its `onSubmit` handler, or as a native form post to its own field names.",
1901
1901
  "forgotPassword": "Go to the page that asks for a password reset link (`data-action=\"forgot-password\"`). Present only when the host gives its address.",
1902
+ "register": "Go to a registration page: `data-action=\"register-doctor\"` or `data-action=\"register-patient\"`, under the sign-in button. Each is present only when the host gives its address.",
1902
1903
  "devSignIn": "Development only: follow one of the quick sign-in links (`data-action=\"dev-login\"`, inside `data-component=\"login-dev-card\"`). Each leads to a route on the host that signs a test account in. The kit holds no test data. The card is present only when the host's server reports a development environment, and the server refuses those routes anywhere else."
1903
1904
  }
1904
1905
  },
package/dist/index.js CHANGED
@@ -264,9 +264,9 @@ import { A as iT, a as pT, L as mT, P as lT, S as dT, T as AT, b as fT, c as cT,
264
264
  import { C as yT, a as kT, b as BT, c as vT, D as GT, d as HT, S as WT, V as wT, W as UT, e as VT, i as KT, m as YT, r as XT, u as qT, f as zT, g as jT } from "./_chunks/calendar-workspace-Ct8_454k.js";
265
265
  import { E as ZT, a as JT, b as $T, e as au, r as eu } from "./_chunks/error-page-DirZKDz2.js";
266
266
  import { E as ru } from "./_chunks/error-page-illustration-BdJLuMdV.js";
267
- import { F as tu, a as nu } from "./_chunks/forgot-password-form-Dqi7R-NL.js";
267
+ import { F as tu, a as nu } from "./_chunks/forgot-password-form-BGPc8TGr.js";
268
268
  import { A as pu, a as mu, H as lu, b as du, u as Au } from "./_chunks/help-me-write-templates-5WkUfvc_.js";
269
- import { L as cu, a as Su, b as gu } from "./_chunks/login-dev-card-vEL-o5wq.js";
269
+ import { L as cu, a as Su, b as gu } from "./_chunks/login-dev-card-CWpoTuVY.js";
270
270
  import { C as xu, M as Tu, P as uu } from "./_chunks/marketplace-app-shell-CcLQ0Dn-.js";
271
271
  import { P as Eu } from "./_chunks/payment-automation-upsell-CiwF5UrC.js";
272
272
  import { R as Ru, a as _u } from "./_chunks/registration-form-1B0PTDal.js";
@@ -5,11 +5,12 @@ export interface AuthTextLinkProps {
5
5
  href: string;
6
6
  /** Emitted as `data-action`. */
7
7
  action: string;
8
+ /** Default `center`. */
9
+ align?: 'center' | 'end';
8
10
  children: ReactNode;
9
11
  }
10
- /** The quiet link under the card's button: "Forgot password?", "Back to
11
- * sign in". */
12
- export declare function AuthTextLink({ href, action, children }: AuthTextLinkProps): import("react/jsx-runtime").JSX.Element;
12
+ /** A quiet link in the card: "Forgot password?", "Back to sign in". */
13
+ export declare function AuthTextLink({ href, action, align, children, }: AuthTextLinkProps): import("react/jsx-runtime").JSX.Element;
13
14
  export interface AuthCardHeadingProps {
14
15
  /** The id the form is labelled by. */
15
16
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"auth-form-parts.d.ts","sourceRoot":"","sources":["../../../src/patterns/_shared/auth-form-parts.tsx"],"names":[],"mappings":"AASA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG9D,OAAO,EAAS,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGnE,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AA+B/D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;gBACgB;AAChB,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,iBAAiB,2CAMzE;AAED,MAAM,WAAW,oBAAoB;IACnC,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED,mDAAmD;AACnD,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,UAAU,GACX,EAAE,oBAAoB,2CAgBtB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;kEAC8D;IAC9D,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,mEAAmE;AACnE,eAAO,MAAM,eAAe,iHAc3B,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,EACpE,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,GACzD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAepB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,GAAG,SAAS,CAcpB;AAED,0CAA0C;AAC1C,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;CAAE,2CAQrE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,2CAOzD"}
1
+ {"version":3,"file":"auth-form-parts.d.ts","sourceRoot":"","sources":["../../../src/patterns/_shared/auth-form-parts.tsx"],"names":[],"mappings":"AASA,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG9D,OAAO,EAAS,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGnE,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAsC/D,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,KAAK,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IACzB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,MAAM,EACN,KAAK,EACL,QAAQ,GACT,EAAE,iBAAiB,2CAMnB;AAED,MAAM,WAAW,oBAAoB;IACnC,sCAAsC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED,mDAAmD;AACnD,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,UAAU,GACX,EAAE,oBAAoB,2CAgBtB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;kEAC8D;IAC9D,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,mEAAmE;AACnE,eAAO,MAAM,eAAe,iHAc3B,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,EACpE,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,GACzD,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAepB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,GAAG,SAAS,CAcpB;AAED,0CAA0C;AAC1C,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;CAAE,2CAQrE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,2CAOzD"}
@@ -1,4 +1,4 @@
1
- import { F as r, a } from "../../_chunks/forgot-password-form-Dqi7R-NL.js";
1
+ import { F as r, a } from "../../_chunks/forgot-password-form-BGPc8TGr.js";
2
2
  export {
3
3
  r as FORGOT_PASSWORD_FORM_FIELDS,
4
4
  a as ForgotPasswordForm
@@ -1,4 +1,4 @@
1
- import { L, a as r, b as s } from "../../_chunks/login-dev-card-vEL-o5wq.js";
1
+ import { L, a as r, b as s } from "../../_chunks/login-dev-card-CWpoTuVY.js";
2
2
  export {
3
3
  L as LOGIN_FORM_FIELDS,
4
4
  r as LoginDevCard,
@@ -68,11 +68,15 @@ export interface LoginFormProps extends Omit<HTMLAttributes<HTMLDivElement>, 'ti
68
68
  */
69
69
  errors?: LoginFormErrors;
70
70
  /**
71
- * Adds "Forgot password?" under the button. A path on the same site,
71
+ * Adds "Forgot password?" under the password. A path on the same site,
72
72
  * or an address written in full (`https://…`). Anything else shows no
73
- * link.
73
+ * link. The same rule holds for the two addresses below.
74
74
  */
75
75
  forgotPasswordHref?: string;
76
+ /** Adds "Register as a doctor" under the button. */
77
+ registerDoctorHref?: string;
78
+ /** Adds "Register as a patient" under the button. */
79
+ registerPatientHref?: string;
76
80
  /** Replaces the button's "Sign in". Pass it translated. */
77
81
  submitLabel?: string;
78
82
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"login-form.d.ts","sourceRoot":"","sources":["../../../src/patterns/login-form/login-form.tsx"],"names":[],"mappings":"AAaA,OAAO,EAML,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAsBf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAW7D,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,gCAAiC,CAAC;AAEhE,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,6DAA6D;AAC7D,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;6DAC6D;AAC7D,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7E;;8BAE8B;AAC9B,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/E;oDACoD;AACpD,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AAEjE,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,cAAc,CAAC,cAAc,CAAC,EAC9B,OAAO,GAAG,UAAU,CACrB;IACC,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;yDACqD;IACrD,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;uDACmD;IACnD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAC7C;;;;OAIG;IACH,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAuCD;;;GAGG;AACH,eAAO,MAAM,SAAS,2GAiWrB,CAAC"}
1
+ {"version":3,"file":"login-form.d.ts","sourceRoot":"","sources":["../../../src/patterns/login-form/login-form.tsx"],"names":[],"mappings":"AAaA,OAAO,EAML,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAsBf,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAW7D,wDAAwD;AACxD,eAAO,MAAM,iBAAiB,gCAAiC,CAAC;AAEhE,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhE,6DAA6D;AAC7D,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;6DAC6D;AAC7D,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7E;;8BAE8B;AAC9B,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/E;oDACoD;AACpD,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AAEjE,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,cAAc,CAAC,cAAc,CAAC,EAC9B,OAAO,GAAG,UAAU,CACrB;IACC,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;yDACqD;IACrD,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oDAAoD;IACpD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qDAAqD;IACrD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;uDACmD;IACnD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAC7C;;;;OAIG;IACH,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAiDD;;;GAGG;AACH,eAAO,MAAM,SAAS,2GA0XrB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfadocs/ui-kit-debug",
3
- "version": "1.70.0",
3
+ "version": "1.71.0",
4
4
  "type": "module",
5
5
  "description": "AlfaDocs shared design system — tokens, components, patterns, and translations for platform, booking, and alfascribe. (debug build — identical runtime to @alfadocs/ui-kit, ships source maps for symbolication).",
6
6
  "license": "BUSL-1.1",
@@ -1,86 +0,0 @@
1
- import { jsxs as m, jsx as r, Fragment as v } from "react/jsx-runtime";
2
- import { useEffect as f, forwardRef as h } from "react";
3
- import { c as l } from "./index-D2ZczOXr.js";
4
- import { useTranslation as g } from "react-i18next";
5
- import { A as c } from "./alert-9kEwDza3.js";
6
- import { i as u } from "./is-development-CLUAnsU7.js";
7
- import { a as p } from "./safe-href-5dbsfbQn.js";
8
- import { B as b } from "./use-registration-submit-eWAECgUC.js";
9
- const x = "Alfadocs", w = l(
10
- "ds:flex ds:min-w-0 ds:flex-col ds:gap-[var(--spacing-xs)]",
11
- {
12
- variants: {
13
- centred: { true: "ds:items-center ds:text-center", false: "" }
14
- },
15
- defaultVariants: { centred: !0 }
16
- }
17
- ), A = l(
18
- "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)] ds:forced-colors:focus-visible:outline-[CanvasText]"
19
- ), N = l(
20
- 'type-body-sm ds:relative ds:self-center ds:rounded-[var(--radius-sm)] ds:underline ds:underline-offset-4 ds:text-[var(--foreground)] ds:before:absolute ds:before:inset-x-0 ds:before:inset-y-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[""] 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)] ds:forced-colors:focus-visible:outline-[CanvasText]'
21
- );
22
- function S({ href: s, action: e, children: t }) {
23
- return /* @__PURE__ */ r("a", { href: s, "data-action": e, className: N(), children: t });
24
- }
25
- function V({
26
- id: s,
27
- title: e,
28
- description: t,
29
- level: a,
30
- showLogo: o,
31
- logoMotion: d
32
- }) {
33
- const i = `h${a}`;
34
- return /* @__PURE__ */ m("div", { className: w({ centred: o }), children: [
35
- o && /* @__PURE__ */ r(b, { motion: d, label: x }),
36
- /* @__PURE__ */ r(i, { id: s, className: "type-title-card", children: e }),
37
- t && /* @__PURE__ */ r("p", { className: "type-body-sm ds:text-[var(--muted-foreground)]", children: t })
38
- ] });
39
- }
40
- const y = h(
41
- ({ id: s, announce: e, children: t }, a) => /* @__PURE__ */ r(
42
- c,
43
- {
44
- ref: a,
45
- id: s,
46
- variant: "error",
47
- announce: e,
48
- tabIndex: -1,
49
- "data-field": "form",
50
- className: A(),
51
- children: /* @__PURE__ */ r(c.Description, { children: t })
52
- }
53
- )
54
- );
55
- y.displayName = "AuthFormMessage";
56
- function C(s, e, t, a) {
57
- const o = new Set(Object.values(t ?? {})), d = e ? Object.entries(a ?? {}) : [], i = d.filter(([n]) => o.has(n)).map(([n]) => n).join(", ");
58
- return f(() => {
59
- i && u() && console.warn(
60
- `${s}: hiddenFields "${i}" is also named in fieldNames and was left out. The form's own field wins.`
61
- );
62
- }, [i, s]), d.filter(([n]) => !o.has(n));
63
- }
64
- function D(s, e, t) {
65
- const a = e && t && p(t) ? t : void 0, o = t ? e ? a ? void 0 : "`action` is not a path or an address on this origin and was left out. The form posts to the current address." : "`action` does nothing without `fieldNames`: only a native form post has an address." : void 0;
66
- return f(() => {
67
- o && u() && console.warn(`${s}: ${o}`);
68
- }, [s, o]), a;
69
- }
70
- function H({ fields: s }) {
71
- return /* @__PURE__ */ r(v, { children: s.map(([e, t]) => /* @__PURE__ */ r("input", { type: "hidden", name: e, value: t }, e)) });
72
- }
73
- function O({ busy: s }) {
74
- const { t: e } = g("ui");
75
- return /* @__PURE__ */ r("p", { role: "status", className: "ds:sr-only", children: s ? e("chat.message.status.sending") : "" });
76
- }
77
- export {
78
- V as A,
79
- H as E,
80
- C as a,
81
- y as b,
82
- O as c,
83
- S as d,
84
- D as u
85
- };
86
- //# sourceMappingURL=auth-form-parts-B40zvD-a.js.map
@@ -1,309 +0,0 @@
1
- import { jsxs as v, jsx as e } from "react/jsx-runtime";
2
- import { forwardRef as ls, useId as N, useState as n, useRef as es, useEffect as bs } from "react";
3
- import { useTranslation as ys } from "react-i18next";
4
- import { c as j } from "./index-D2ZczOXr.js";
5
- import { i as as, E as Es } from "./email-input-C7THAwh2.js";
6
- import { B as ds } from "./button-D-MQxsA_.js";
7
- import { C as h } from "./card-BA4Ig_kn.js";
8
- import { E as Ns } from "./error-summary-mGxIyDAY.js";
9
- import { F as rs } from "./form-field-Ani72sVY.js";
10
- import { P as Is } from "./password-input-BokZ_rnT.js";
11
- import { i as is } from "./safe-href-5dbsfbQn.js";
12
- import { u as Bs } from "./use-state-backed-input-DhRQo6gM.js";
13
- import { u as Rs, a as Ls, A as As, b as Cs, E as Ms, d as Ss, c as ks } from "./auth-form-parts-B40zvD-a.js";
14
- import { u as qs, b as zs, a as js } from "./use-registration-submit-eWAECgUC.js";
15
- import { M as $s } from "./matrix-rain-sDOUUwZp.js";
16
- import { a as Ds } from "./error-page-illustration-BdJLuMdV.js";
17
- const $ = ["email", "password"], Ps = j(
18
- "ds:flex ds:w-full ds:flex-col ds:items-center ds:justify-center ds:gap-[var(--spacing-lg)] ds:text-start ds:text-[var(--foreground)] ds:lg:flex-row ds:lg:items-stretch"
19
- ), os = j("ds:w-full ds:max-w-[400px]"), Ts = (r) => Object.values(r).some(Boolean), Os = (r) => $.some((d) => !!r[d]), ts = (r) => $.find((d) => r[d]) ?? (r.form ? "password" : void 0), Hs = ls(
20
- ({
21
- title: r,
22
- description: d,
23
- headingLevel: w = 1,
24
- showLogo: I = !0,
25
- logoMotion: B = "assemble",
26
- children: x,
27
- initialValues: o,
28
- errors: c,
29
- forgotPasswordHref: m,
30
- submitLabel: t,
31
- submitting: R = !1,
32
- onSubmit: L,
33
- fieldNames: F,
34
- action: ns,
35
- hiddenFields: cs,
36
- devCard: D,
37
- className: ms,
38
- ...us
39
- }, fs) => {
40
- const { t: l } = ys("ui"), P = N(), A = N(), ps = N(), C = (s) => `${ps}-${s}`, u = F !== void 0, [f, M] = n(() => (o == null ? void 0 : o.email) ?? ""), [b, y] = n(""), [gs, T] = n(() => ({ email: !!(o != null && o.email) })), [vs, O] = n(!1), [H, _] = n(
41
- () => c ?? {}
42
- ), G = (s) => T(
43
- (a) => a[s] ? a : { ...a, [s]: !0 }
44
- ), W = (s) => _(
45
- (a) => a[s] ? { ...a, [s]: void 0 } : a
46
- ), S = es(null), k = es(null), J = Bs(f, S), K = () => {
47
- y(""), T((s) => ({ ...s, password: !1 }));
48
- }, Q = () => {
49
- var a, g;
50
- const s = {
51
- email: ((a = S.current) == null ? void 0 : a.value) ?? f,
52
- password: ((g = k.current) == null ? void 0 : g.value) ?? b
53
- };
54
- return s.email !== f && M(s.email), s.password !== b && y(s.password), s;
55
- }, U = {
56
- email: !as(f),
57
- password: b === ""
58
- }, X = (s) => vs || gs[s] === !0, hs = {
59
- email: X("email") && U.email ? l(f === "" ? "loginForm.emailRequired" : "inputs.email.invalid") : void 0,
60
- password: X("password") && U.password ? l("loginForm.passwordRequired") : void 0
61
- }, E = (s) => H[s] ?? hs[s], [Y] = n(
62
- () => Os(c ?? {})
63
- ), i = qs(
64
- $,
65
- E,
66
- Y
67
- ), [q, Z] = n(() => {
68
- const s = Y ? void 0 : ts(c ?? {});
69
- return s ? { target: s } : null;
70
- });
71
- bs(() => {
72
- var s;
73
- q && ((s = (q.target === "email" ? S : k).current) == null || s.focus());
74
- }, [q]);
75
- const V = zs({
76
- errors: c,
77
- submitting: R,
78
- native: u,
79
- captcha: !1,
80
- firstProblem: () => {
81
- const s = Q();
82
- return as(s.email) ? s.password === "" ? "password" : void 0 : "email";
83
- },
84
- onRefused: (s) => {
85
- O(!0), i.open(() => Z({ target: s }));
86
- },
87
- // Only a React host gets here: a native post is the browser's own.
88
- deliver: () => L == null ? void 0 : L(Q()),
89
- onAnswer: (s) => {
90
- const a = s;
91
- _(a), Ts(a) && (K(), O(!1), i.open(() => {
92
- const g = ts(a);
93
- g && Z({ target: g });
94
- }));
95
- },
96
- // The page came back from the browser's cache as it was left: the
97
- // password must not come back with it.
98
- onRestore: K
99
- }), { busy: z } = V, ws = Rs("LoginForm", u, ns), ss = m && is(m) ? m : void 0, xs = Ls(
100
- "LoginForm",
101
- u,
102
- F,
103
- cs
104
- ), p = H.form, Fs = js(
105
- p,
106
- i.listed.length > 0
107
- );
108
- return /* @__PURE__ */ v(
109
- "div",
110
- {
111
- ref: fs,
112
- ...us,
113
- "data-component": "login-form",
114
- className: Ps({ className: ms }),
115
- children: [
116
- /* @__PURE__ */ e("div", { className: os(), children: /* @__PURE__ */ e(h, { variant: "elevated", className: "ds:h-full", children: /* @__PURE__ */ v(h.Body, { className: "ds:flex ds:flex-col ds:gap-[var(--spacing-lg)]", children: [
117
- /* @__PURE__ */ e(
118
- As,
119
- {
120
- id: P,
121
- title: r ?? l("loginForm.title"),
122
- description: d,
123
- level: w,
124
- showLogo: I,
125
- logoMotion: B
126
- }
127
- ),
128
- x ? /* @__PURE__ */ e(
129
- "div",
130
- {
131
- "data-slot": "host-content",
132
- className: "ds:flex ds:flex-col ds:gap-[var(--spacing-md)]",
133
- children: x
134
- }
135
- ) : null,
136
- /* @__PURE__ */ v(
137
- "form",
138
- {
139
- noValidate: !0,
140
- method: "post",
141
- action: ws,
142
- "aria-labelledby": P,
143
- "aria-busy": z || void 0,
144
- onSubmit: V.handleSubmit,
145
- className: "ds:flex ds:flex-col ds:gap-[var(--spacing-md)]",
146
- children: [
147
- /* @__PURE__ */ e(
148
- Ns,
149
- {
150
- ref: i.ref,
151
- headingLevel: w + 1,
152
- "aria-describedby": p ? A : void 0,
153
- errors: i.listed.map((s) => ({
154
- field: s,
155
- message: E(s) ?? "",
156
- targetId: C(s)
157
- }))
158
- }
159
- ),
160
- p && /* @__PURE__ */ e(
161
- Cs,
162
- {
163
- id: A,
164
- announce: Fs,
165
- children: p
166
- }
167
- ),
168
- /* @__PURE__ */ e(
169
- rs,
170
- {
171
- id: C("email"),
172
- label: l("loginForm.email"),
173
- required: !0,
174
- error: E("email"),
175
- announceError: !i.lists("email"),
176
- "data-field": "email",
177
- children: /* @__PURE__ */ e(
178
- Es,
179
- {
180
- ref: J.ref,
181
- name: u ? F.email : "email",
182
- autoComplete: "username",
183
- disableBuiltInValidation: !0,
184
- onChange: J.quiet((s) => {
185
- M(s.target.value), W("email");
186
- }),
187
- onBlur: (s) => {
188
- M(s.target.value), s.target.value !== "" && G("email");
189
- }
190
- }
191
- )
192
- }
193
- ),
194
- /* @__PURE__ */ e(
195
- rs,
196
- {
197
- id: C("password"),
198
- label: l("loginForm.password"),
199
- required: !0,
200
- error: E("password"),
201
- announceError: !i.lists("password"),
202
- "data-field": "password",
203
- children: /* @__PURE__ */ e(
204
- Is,
205
- {
206
- ref: k,
207
- name: u ? F.password : "password",
208
- autoComplete: "current-password",
209
- "aria-describedby": p ? A : void 0,
210
- value: b,
211
- onChange: (s) => {
212
- y(s.target.value), W("password");
213
- },
214
- onBlur: (s) => {
215
- y(s.target.value), s.target.value !== "" && G("password");
216
- }
217
- }
218
- )
219
- }
220
- ),
221
- /* @__PURE__ */ e(Ms, { fields: xs }),
222
- /* @__PURE__ */ e(
223
- ds,
224
- {
225
- type: "submit",
226
- intent: "primary",
227
- size: "lg",
228
- loading: z,
229
- className: "ds:w-full",
230
- "data-action": "submit",
231
- children: t ?? l("loginForm.submit")
232
- }
233
- ),
234
- ss && /* @__PURE__ */ e(Ss, { href: ss, action: "forgot-password", children: l("loginForm.forgot") })
235
- ]
236
- }
237
- ),
238
- /* @__PURE__ */ e(ks, { busy: z })
239
- ] }) }) }),
240
- D ? /* @__PURE__ */ e("div", { className: os(), children: D }) : null
241
- ]
242
- }
243
- );
244
- }
245
- );
246
- Hs.displayName = "LoginForm";
247
- const _s = j("ds:h-full ds:w-full"), Gs = ls(
248
- ({ title: r, options: d, headingLevel: w = 2, className: I, ...B }, x) => {
249
- const o = N(), c = `h${w}`, m = d.filter((t) => is(t.href));
250
- return /* @__PURE__ */ e(
251
- "div",
252
- {
253
- ref: x,
254
- ...B,
255
- "data-component": "login-dev-card",
256
- className: _s({ className: I }),
257
- children: /* @__PURE__ */ v(
258
- h,
259
- {
260
- variant: "elevated",
261
- "aria-labelledby": o,
262
- className: "ds:relative ds:isolate ds:flex ds:h-full ds:flex-col ds:overflow-hidden",
263
- children: [
264
- /* @__PURE__ */ e("div", { className: "ds:absolute ds:inset-0 ds:z-0 ds:[display:var(--accessible-off,block)]", children: /* @__PURE__ */ e(
265
- $s,
266
- {
267
- glyphs: "hex",
268
- decay: "fast",
269
- mask: "center",
270
- maskRadius: "xl",
271
- className: "ds:size-full"
272
- }
273
- ) }),
274
- /* @__PURE__ */ e(h.Header, { className: "ds:relative ds:z-[1]", children: /* @__PURE__ */ v("div", { className: "ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)] ds:text-center", children: [
275
- /* @__PURE__ */ e("div", { className: "ds:[&>div]:w-24", children: /* @__PURE__ */ e(Ds, { mood: "melt" }) }),
276
- /* @__PURE__ */ e(
277
- c,
278
- {
279
- id: o,
280
- className: "type-title-card ds:text-[var(--foreground)]",
281
- children: r
282
- }
283
- )
284
- ] }) }),
285
- /* @__PURE__ */ e(h.Body, { className: "ds:relative ds:z-[1] ds:flex ds:flex-1 ds:flex-col ds:justify-center", children: /* @__PURE__ */ e("div", { className: "ds:mt-[var(--spacing-md)] ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]", children: m.map((t, R) => /* @__PURE__ */ e(
286
- ds,
287
- {
288
- asChild: !0,
289
- intent: "primary",
290
- startIcon: t.icon,
291
- className: "ds:min-h-[var(--min-target-size)] ds:w-full",
292
- children: /* @__PURE__ */ e("a", { href: t.href, "data-action": "dev-login", children: t.label })
293
- },
294
- `${R}:${t.href}`
295
- )) }) })
296
- ]
297
- }
298
- )
299
- }
300
- );
301
- }
302
- );
303
- Gs.displayName = "LoginDevCard";
304
- export {
305
- $ as L,
306
- Gs as a,
307
- Hs as b
308
- };
309
- //# sourceMappingURL=login-dev-card-vEL-o5wq.js.map