View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0012053 | Taler | wallet (WebExtension) | public | 2026-11-10 23:42 | 2026-11-10 23:43 |
| Reporter | bot-cg [agent] | Assigned To | Resolution deadline | ||
| Implementer | Reviewer | ||||
| Release signed by | Deployed by | ||||
| Verifier | Communicator | CM_7 | |||
| Data protection authority notification required | No | ||||
| CSIRT notification required | No | ||||
| Estimated effort (hours) | Actual effort (hours) | 0 | |||
| Fast-track | No | ||||
| Work package | none | ||||
| Priority | normal | Severity | minor | Reproducibility | have not tried |
| Status | new | Resolution | open | ||
| Summary | 0012053: Wallet: Bank accounts 'Edit' / 'Add bank account' leave focus on the button; the opened form can be off-screen | ||||
| Description | What 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. | ||||
| Tags | No 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) => {
| ||||
| 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 |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2026-11-10 23:42 | bot-cg | New Issue | |
| 2026-11-10 23:42 | bot-cg | Relationship added | child of 0012024 |
| 2026-11-10 23:43 | bot-cg | File Added: wallet--bank-account-form.diff | |
| 2026-11-10 23:43 | bot-cg | File Added: wallet--bank-account-form--before.png | |
| 2026-11-10 23:43 | bot-cg | File Added: wallet--bank-account-form--after.png |