diff --git a/packages/web-util/src/forms/AcceptTosForm.tsx b/packages/web-util/src/forms/AcceptTosForm.tsx index b2ebdcaa9..d9e74e7a4 100644 --- a/packages/web-util/src/forms/AcceptTosForm.tsx +++ b/packages/web-util/src/forms/AcceptTosForm.tsx @@ -1,6 +1,7 @@ import { TalerFormAttributes } from "@gnu-taler/taler-util"; import { Fragment, type ComponentChildren, h, type VNode } from "preact"; import { useEffect, useRef, useState } from "preact/hooks"; +import { useAutoFocus } from "../components/utils.js"; import { useTranslationContext } from "../context/translation.js"; import type { FormModel } from "../hooks/useForm.js"; import { @@ -114,6 +115,11 @@ function TermsReaderDialog(props: { onClose: () => void; }): VNode { const { onClose } = props; + // The parent passes a new onClose on every render; read it through a ref + // so that a re-render (e.g. when the terms finish loading) does not run the + // open/close effect again and pull focus back to the close button. + const onCloseRef = useRef(onClose); + onCloseRef.current = onClose; const { i18n } = useTranslationContext(); const dialogRef = useRef(null); const closeButtonRef = useRef(null); @@ -143,7 +149,7 @@ function TermsReaderDialog(props: { const onKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { event.preventDefault(); - onClose(); + onCloseRef.current(); return; } const dialog = dialogRef.current; @@ -170,7 +176,7 @@ function TermsReaderDialog(props: { document.body.style.overflow = previousOverflow; previousFocus.current?.focus(); }; - }, [onClose]); + }, []); async function downloadPdf(): Promise { setDownloadState("loading"); @@ -358,6 +364,7 @@ export function AcceptTosForm(props: { const [error, setError] = useState(); const request = useRef(); const readButton = useRef(null); + useAutoFocus(props.focus, () => readButton.current); useEffect( () => () => { @@ -460,7 +467,6 @@ export function AcceptTosForm(props: { disabled={props.disabled} class="mt-5 inline-flex min-h-11 items-center justify-center rounded-md bg-indigo-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 disabled:cursor-default disabled:opacity-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600" onClick={openReader} - autofocus={props.focus} > {hasRead ? readAgainLabel : readLabel}