View Issue Details

IDProjectCategoryView StatusLast Update
0012053Talerwallet (WebExtension)public2026-11-10 23:43
Reporterbot-cg [agent] Assigned ToResolution deadline
ImplementerReviewer 
Release signed byDeployed by 
VerifierCommunicatorCM_7  
Data protection authority notification requiredNo  
CSIRT notification requiredNo  
Estimated effort (hours)Actual effort (hours)0 
Fast-trackNo
Work packagenone
PrioritynormalSeverityminorReproducibilityhave not tried
Status newResolutionopen 
Summary0012053: Wallet: Bank accounts 'Edit' / 'Add bank account' leave focus on the button; the opened form can be off-screen
DescriptionWhat happens:
Settings -> Bank accounts. 'Edit' on an account opens the edit form below the whole account list, but focus stays on the Edit button (with several accounts the form is off-screen and nothing visibly happens). 'Add bank account' expands the add form with focus left on the disclosure button. activeElement: BUTTON 'Edit' / BUTTON 'Add bank account'.

Expected:
Focus (and scroll) to the first text field of the form that was just opened: Payto URI when editing, the first required field (e.g. Account holder name) when adding. The Account-type select is prefilled and skipped, since type-ahead on a focused select would change it.

Where:
  - packages/wallet-webui/src/screens/BankAccountsScreen.tsx:117
  - packages/wallet-webui/src/screens/BankAccountsScreen.tsx:240
  - packages/wallet-webui/src/screens/BankAccountsScreen.tsx:286

Measured in headless Chromium (document.activeElement):
  before: BUTTON 'Edit' (add: BUTTON 'Add bank account', see wallet--bank-account-form-add--*.png)
  after: INPUT 'Payto URI' (add: INPUT 'Account holder name')

Proposed fix:
The Edit and disclosure handlers set a focus request; an effect consumes it once the form shows its fields (for edits, after the existing reset effect has switched to the payto field) and focuses the form's first input. Saving an edit does not move focus.

Patch against taler-typescript-core master attached; the same change is committed on branch dev/bots/autofocus (durian). Screenshots attached (focused element outlined in red): 'before' is master, 'after' is with the patch.

Verified: tsc ok (0 errors in wallet-webui with workspace sources; plain `tsc --noEmit -p .` output identical to baseline, whose errors come from stale taler-util/wallet-core lib/); eslint + prettier clean on changed files; package tests screens/exchange-removal/payment-entry/routing bundled from src: 89/95 pass, the same 6 App-level demo tests fail before and after; scratch test: add -> holder name, edit -> payto URI, end of edit does not refocus; existing screens.test bank-accounts test (Forget dialog focus/restore) still passes; screenshots.
TagsNo tags attached.
Attached Files
wallet--bank-account-form.diff (2,439 bytes)   
diff --git a/packages/wallet-webui/src/screens/BankAccountsScreen.tsx b/packages/wallet-webui/src/screens/BankAccountsScreen.tsx
index 051179b24..0496144e5 100644
--- a/packages/wallet-webui/src/screens/BankAccountsScreen.tsx
+++ b/packages/wallet-webui/src/screens/BankAccountsScreen.tsx
@@ -114,6 +114,16 @@ export function BankAccountsScreen(props: {
     setPaytoUri(props.editing?.paytoUri ?? "");
     setMethod(props.editing ? "advanced" : (guidedMethods[0] ?? "advanced"));
   }, [guidedMethods, props.editing]);
+  // Opening the form or starting an edit moves focus to its first text field,
+  // which also brings the form into view below the account list. An edit
+  // shows the payto URI field only once the reset above has switched to it.
+  const form = useRef<HTMLFormElement>(null);
+  const focusForm = useRef(false);
+  useEffect(() => {
+    if (!focusForm.current || (props.editing && method !== "advanced")) return;
+    focusForm.current = false;
+    form.current?.querySelector("input")?.focus();
+  });
   const wireType = props.wireTypes?.find(
     (entry) => entry.paymentTargetType === method,
   );
@@ -227,6 +237,7 @@ export function BankAccountsScreen(props: {
                 <Button
                   tone="secondary"
                   onClick={() => {
+                    focusForm.current = true;
                     setFormOpen(true);
                     props.onEdit(account.id);
                   }}
@@ -272,7 +283,10 @@ export function BankAccountsScreen(props: {
               type="button"
               aria-expanded={formOpen}
               aria-controls="bank-account-form"
-              onClick={() => setFormOpen((open) => !open)}
+              onClick={() => {
+                focusForm.current = !formOpen;
+                setFormOpen((open) => !open);
+              }}
               class="flex min-h-12 w-full items-center gap-3 px-4 py-3 text-left text-primary transition hover:bg-secondaryContainer focus:outline-none focus:ring-2 focus:ring-inset focus:ring-primary"
             >
               <span
@@ -291,6 +305,7 @@ export function BankAccountsScreen(props: {
           )}
           {(formOpen || props.editing) && (
             <form
+              ref={form}
               id="bank-account-form"
               class={`form-field-stack space-y-5 p-5 sm:p-6 ${props.editing ? "" : "border-t border-outlineVariant"}`}
               onSubmit={(event) => {
wallet--bank-account-form.diff (2,439 bytes)   

Required notifications

Address or linkRemarkAdded byNotifiedActions

Relationships

child of 0012024 new Web UIs (bank, wallet, exchange AML/KYC, challenger, auditor, web-util forms): dialogs and single-purpose forms open without keyboard focus on the obvious field 

Activities

Issue History

Date ModifiedUsernameFieldChange
2026-11-10 23:42bot-cgNew Issue
2026-11-10 23:42bot-cgRelationship addedchild of 0012024
2026-11-10 23:43bot-cgFile Added: wallet--bank-account-form.diff
2026-11-10 23:43bot-cgFile Added: wallet--bank-account-form--before.png
2026-11-10 23:43bot-cgFile Added: wallet--bank-account-form--after.png