View Issue Details

IDProjectCategoryView StatusLast Update
0012047Talerwallet (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 
Summary0012047: Wallet: Send money / Request money form does not focus the amount
DescriptionWhat happens:
Balances -> Send (#/peer/send) or Request (#/peer/request). The form is rendered after the payment scopes load; nothing is focused, so the user must click the big amount field before typing. Returning from the review step with 'Change' also leaves focus nowhere (the input that was focused was unmounted on submit). Measured activeElement: BODY on both routes (demo wallet, 420x760).

Expected:
The amount field (the only thing that must be typed first on this dedicated screen) is focused when the form appears and again when coming back from review.

Where:
  - packages/wallet-webui/src/screens/PeerCreateScreen.tsx:192
  - packages/wallet-webui/src/screens/PeerCreateScreen.tsx:345

Measured in headless Chromium (document.activeElement):
  before: BODY (nothing focused)
  after: INPUT aria-label="Amount (CHF)" (same on #/peer/request, see wallet--peer-create-request--*.png)

Proposed fix:
Pass a ref to MoneyAmountInput and focus it (preventScroll) in an effect keyed on the form being visible (not loading, scopes available, not in review). The visibility condition is hoisted into `formVisible` and reused for rendering.

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 happy-dom test: focus after async scope load and after review->back; demo-app screenshots before/after.
TagsNo tags attached.
Attached Files
wallet--peer-create.diff (1,684 bytes)   
diff --git a/packages/wallet-webui/src/screens/PeerCreateScreen.tsx b/packages/wallet-webui/src/screens/PeerCreateScreen.tsx
index 18f8bb33d..f2574e5b8 100644
--- a/packages/wallet-webui/src/screens/PeerCreateScreen.tsx
+++ b/packages/wallet-webui/src/screens/PeerCreateScreen.tsx
@@ -189,6 +189,13 @@ export function PeerCreateScreen(props: {
         : { kind: "days", days: Number(expirationMode) as 1 | 7 | 30 };
   const validExpiration =
     expiration.kind !== "custom" || Boolean(expiration.value);
+  const amountInput = useRef<HTMLInputElement>(null);
+  const formVisible = !props.review && !props.loading && !scopeUnavailable;
+  // The form appears only after the scopes have loaded, and again when
+  // returning from the review step; the amount is what the user enters first.
+  useEffect(() => {
+    if (formVisible) amountInput.current?.focus({ preventScroll: true });
+  }, [formVisible]);
   useEffect(() => {
     const sequence = ++previewSequence.current;
     const resolveDefaultExpiration = props.onResolveDefaultExpiration;
@@ -291,7 +298,7 @@ export function PeerCreateScreen(props: {
         </Card>
       )}
       {props.error && <ErrorCard error={props.error} />}
-      {!props.review && !props.loading && !scopeUnavailable && (
+      {formVisible && (
         <form
           class="space-y-6"
           onSubmit={(event) => {
@@ -336,6 +343,7 @@ export function PeerCreateScreen(props: {
             </select>
           </label>
           <MoneyAmountInput
+            inputRef={amountInput}
             // Translators: %1$s is an ISO-style currency code.
             label={i18n.str`Amount (${currency})`}
             value={amount}
wallet--peer-create.diff (1,684 bytes)   
wallet--peer-create--before.png (36,103 bytes)   
wallet--peer-create--before.png (36,103 bytes)   
wallet--peer-create--after.png (36,186 bytes)   
wallet--peer-create--after.png (36,186 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--peer-create.diff
2026-11-10 23:43bot-cgFile Added: wallet--peer-create--before.png
2026-11-10 23:43bot-cgFile Added: wallet--peer-create--after.png