fix: replace visibility:hidden with smooth collapse for zero-tx warning
All checks were successful
check / check (push) Successful in 10s

Instead of permanently reserving space with visibility:hidden, the warning
container now uses max-height + opacity transitions. Space is reserved during
the async check, then smoothly collapses to 0 if the warning isn't needed.
This reclaims ~40px of popup viewport in the common case.
This commit is contained in:
user
2026-02-28 15:37:27 -08:00
parent 8c071ae508
commit 576fe3ab15
2 changed files with 24 additions and 9 deletions

View File

@@ -580,7 +580,14 @@
<div <div
id="confirm-recipient-warning" id="confirm-recipient-warning"
class="mb-2" class="mb-2"
style="visibility: hidden" style="
overflow: hidden;
transition:
max-height 0.3s ease,
opacity 0.3s ease;
max-height: 60px;
opacity: 0;
"
> >
<div <div
class="border border-red-500 border-dashed p-2 text-xs font-bold text-red-500" class="border border-red-500 border-dashed p-2 text-xs font-bold text-red-500"

View File

@@ -243,10 +243,11 @@ function show(txInfo) {
state.viewData = { pendingTx: txInfo }; state.viewData = { pendingTx: txInfo };
showView("confirm-tx"); showView("confirm-tx");
// Reset recipient warning: reserve space (visibility:hidden) while // Reset recipient warning: reserve space (max-height) while the async
// the async check runs, preventing layout shift per README policy. // check runs, then collapse smoothly if not needed.
const recipientWarning = $("confirm-recipient-warning"); const recipientWarning = $("confirm-recipient-warning");
recipientWarning.style.visibility = "hidden"; recipientWarning.style.maxHeight = "60px";
recipientWarning.style.opacity = "0";
estimateGas(txInfo); estimateGas(txInfo);
checkRecipientHistory(txInfo); checkRecipientHistory(txInfo);
@@ -301,18 +302,25 @@ async function checkRecipientHistory(txInfo) {
// the nonce, i.e. sent-tx count only). // the nonce, i.e. sent-tx count only).
const code = await provider.getCode(txInfo.to); const code = await provider.getCode(txInfo.to);
if (code && code !== "0x") { if (code && code !== "0x") {
// Contract address — no warning needed, keep space reserved // Contract address — no warning needed, collapse smoothly
// but invisible to prevent layout shift el.style.maxHeight = "0";
el.style.opacity = "0";
return; return;
} }
const txCount = await provider.getTransactionCount(txInfo.to); const txCount = await provider.getTransactionCount(txInfo.to);
if (txCount === 0) { if (txCount === 0) {
el.style.visibility = "visible"; // Show warning: fade in (space already reserved)
el.style.opacity = "1";
} else {
// Recipient has history — collapse the reserved space smoothly
el.style.maxHeight = "0";
el.style.opacity = "0";
} }
// If txCount > 0, leave visibility:hidden — space stays reserved
} catch (e) { } catch (e) {
log.errorf("recipient history check failed:", e.message); log.errorf("recipient history check failed:", e.message);
// On error, leave visibility:hidden — no layout shift, no false warning // On error, collapse space — no false warning
el.style.maxHeight = "0";
el.style.opacity = "0";
} }
} }