View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0012047 | 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 | 0012047: Wallet: Send money / Request money form does not focus the amount | ||||
| Description | What 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. | ||||
| Tags | No 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}
| ||||
| 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--peer-create.diff | |
| 2026-11-10 23:43 | bot-cg | File Added: wallet--peer-create--before.png | |
| 2026-11-10 23:43 | bot-cg | File Added: wallet--peer-create--after.png |