View Issue Details

IDProjectCategoryView StatusLast Update
0012060Talerotherpublic2026-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
PrioritynormalSeveritytweakReproducibilityhave not tried
Status newResolutionopen 
Summary0012060: web-util: Header settings panel: closing it with × drops focus to the page body
DescriptionWhat happens:
The shared Header (AML, bank and KYC frames) opens its settings slide-over and focuses the × close button correctly; Escape returns focus to the menu toggle. Closing with the × button (keyboard Enter/Space or click) unmounts the focused button and leaves focus on BODY, so the next Tab starts again from the top of the page.

Expected:
Closing the panel by any means returns focus to the menu toggle that opened it.

Where:
  - packages/web-util/src/components/Header.tsx:42

Measured in headless Chromium (document.activeElement):
  before: open: BUTTON[name='close sidebar'] (correct); after × : BODY
  after: open: BUTTON[name='close sidebar']; after ×: BUTTON[name='toggle sidebar']; after Escape: BUTTON[name='toggle sidebar']

Proposed fix:
The open-panel effect's cleanup focuses the menu toggle when focus has fallen to the body (it does not override focus the user placed elsewhere).

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; eslint clean; stories-utils tests pass; Chromium header scenario before/after
TagsNo tags attached.
Attached Files
web-util--header-menu-close.diff (1,117 bytes)   
diff --git a/packages/web-util/src/components/Header.tsx b/packages/web-util/src/components/Header.tsx
index ac5bc89a6..527fce1b9 100644
--- a/packages/web-util/src/components/Header.tsx
+++ b/packages/web-util/src/components/Header.tsx
@@ -37,6 +37,7 @@ export function Header({
   const closeButton = useRef<HTMLButtonElement>(null);
   useEffect(() => {
     if (!open) return;
+    const toggle = menuButton.current;
     closeButton.current?.focus();
     function closeOnEscape(event: KeyboardEvent): void {
       if (event.key === "Escape") {
@@ -45,7 +46,14 @@ export function Header({
       }
     }
     document.addEventListener("keydown", closeOnEscape);
-    return () => document.removeEventListener("keydown", closeOnEscape);
+    return () => {
+      document.removeEventListener("keydown", closeOnEscape);
+      // Closing removes the focused panel button; return focus to the toggle
+      // instead of leaving it on the page body.
+      if (document.activeElement === document.body) {
+        toggle?.focus();
+      }
+    };
   }, [open]);
   // const ns = useNotifications();
   return (
web-util--header--before.png (12,072 bytes)   
web-util--header--before.png (12,072 bytes)   
web-util--header--after.png (13,128 bytes)   
web-util--header--after.png (13,128 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: web-util--header-menu-close.diff
2026-11-10 23:43bot-cgFile Added: web-util--header--before.png
2026-11-10 23:43bot-cgFile Added: web-util--header--after.png