View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0012049 | 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 | 0012049: Wallet: Withdraw screen's existing amount auto-focus never fires on #/withdraw | ||||
| Description | What happens: WithdrawalScreen already had `useEffect(() => amountInput.current?.focus(), [props.amountEditable])`, but on the ordinary #/withdraw route the screen mounts with loading=true and no providers, so the amount input does not exist yet when the effect runs, and it never runs again when the exchanges arrive. Only the bank-integrated route (providers present at mount) got focus. activeElement on #/withdraw: BODY. Expected: Amount focused as soon as it is rendered (unless the amount is fixed by the bank/exchange, or a cash acceptor decides it). Where: - packages/wallet-webui/src/screens/WithdrawalScreen.tsx:63 Measured in headless Chromium (document.activeElement): before: BODY (nothing focused) after: INPUT aria-label="Amount to withdraw in CHF" Proposed fix: Key the effect on whether the amount field is shown (`provider !== undefined && !cashAcceptor`) as well as amountEditable; focus with preventScroll. 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: loading -> providers focuses amount; amountEditable=false does not; screenshots. | ||||
| Tags | No tags attached. | ||||
| Attached Files | wallet--withdraw.diff (1,281 bytes)
diff --git a/packages/wallet-webui/src/screens/WithdrawalScreen.tsx b/packages/wallet-webui/src/screens/WithdrawalScreen.tsx
index 20a612835..0b4b26f88 100644
--- a/packages/wallet-webui/src/screens/WithdrawalScreen.tsx
+++ b/packages/wallet-webui/src/screens/WithdrawalScreen.tsx
@@ -60,9 +60,15 @@ export function WithdrawalScreen(props: {
useEffect(() => {
if (!amount && props.initialAmount) setAmount(props.initialAmount);
}, [amount, props.initialAmount]);
+ // The amount field is only rendered once the exchanges have loaded, which
+ // is usually after the first render. It sits at the top of the page, so
+ // focusing it need not scroll; scrolling would also make the story
+ // catalogue, which shows many screens at once, jump to this one.
+ const amountShown = provider !== undefined && !props.cashAcceptor;
useEffect(() => {
- if (props.amountEditable !== false) amountInput.current?.focus();
- }, [props.amountEditable]);
+ if (amountShown && props.amountEditable !== false)
+ amountInput.current?.focus({ preventScroll: true });
+ }, [amountShown, props.amountEditable]);
const enteredAmount = positiveAmountValue(provider?.currency ?? "", amount);
const normalizedAmount = positiveAmountValue(
provider?.currency ?? "",
| ||||
| 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 |