diff --git a/packages/taler-merchant-webui/src/screens/AccessScreen.tsx b/packages/taler-merchant-webui/src/screens/AccessScreen.tsx index 369270c33..97f8f35ca 100644 --- a/packages/taler-merchant-webui/src/screens/AccessScreen.tsx +++ b/packages/taler-merchant-webui/src/screens/AccessScreen.tsx @@ -16,7 +16,7 @@ import { FormActionFooter, useFormFeedback } from "../ui/FormActionFooter.js"; import type { VNode } from "preact"; -import { useEffect, useState } from "preact/hooks"; +import { useEffect, useRef, useState } from "preact/hooks"; import { useLocation } from "wouter-preact"; import { Header } from "../ui/Header.js"; import { TalerQrCode } from "../ui/TalerQrCode.js"; @@ -134,6 +134,18 @@ export function AccessScreen({ setPairingError(undefined); }, [issuedPairingCredential, setPairingError]); + // This dialog is drawn here rather than by Modal, so it places focus itself: + // in the device name when it opens, and on the heading of the credential + // step, whose arrival removes the focused form and would otherwise drop + // focus to the page, out of reach of the dialog's Escape handler. + const pairNameInput = useRef(null); + const pairQrHeading = useRef(null); + useEffect(() => { + if (!showPairModal) return; + if (pairStep === "form") pairNameInput.current?.focus(); + else pairQrHeading.current?.focus(); + }, [showPairModal, pairStep]); + const displayTokens = tokensResource?.data ?? propTokens ?? []; const isInitiallyLoading = tokensResource?.isLoading === true && tokensResource.data === undefined; @@ -484,6 +496,7 @@ export function AccessScreen({ {t`Device Name`} *
-

{t`Scan this with the till app`}

+

{t`Scan this with the till app`}

{t`ℹ️ This credential is shown once. Anyone who has it can use the granted till access.`}