From 98a07daa35a91bee032ea0a3e1c86218cd8d460a Mon Sep 17 00:00:00 2001 From: riyadhafraa <49757212-riyadhafraa@users.noreply.replit.com> Date: Wed, 20 May 2026 12:04:35 +0000 Subject: [PATCH] Improve dialog positioning to better handle mobile keyboards Adjust dialog positioning on mobile to anchor to the top of the visual viewport when the keyboard is open, ensuring content remains accessible and preventing overlap. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 8ed39e54-3a41-4a5b-a3e7-13162e8f9590 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/qrzw3bH Replit-Helium-Checkpoint-Created: true --- artifacts/tx-os/src/components/ui/dialog.tsx | 22 +++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/artifacts/tx-os/src/components/ui/dialog.tsx b/artifacts/tx-os/src/components/ui/dialog.tsx index 105a9a33..fa003580 100644 --- a/artifacts/tx-os/src/components/ui/dialog.tsx +++ b/artifacts/tx-os/src/components/ui/dialog.tsx @@ -41,11 +41,23 @@ const DialogContent = React.forwardRef< const keyboardOpen = keyboardInset > 80 const dynamicStyle: React.CSSProperties = keyboardOpen ? { - // Center the dialog inside the *visible* visual viewport (above - // the keyboard) rather than the layout viewport. offsetTop - // accounts for the page being scrolled or pinch-zoomed. - top: `${offsetTop + height / 2}px`, - maxHeight: `${height - 16}px`, + // Anchor the dialog to the TOP of the visible visual viewport + // (right under the iOS status bar) and let it take the full + // available height above the keyboard. Anchoring (vs centering) + // is critical for tall forms — when the dialog is centered and + // the form has many fields, the footer slides into the middle + // of the visible area and the bottom half of the form ends up + // hidden behind the keyboard. With top-anchor + maxHeight, the + // dialog's own flex column (header / scrollable middle / + // footer) keeps Save/Cancel pinned above the keyboard and the + // rest of the form scrolls inside. + // + // The override of `transform` is necessary because the class + // string below applies `translate-y-[-50%]`; we need to keep + // the horizontal centering but cancel the vertical one. + top: `${offsetTop}px`, + maxHeight: `${height - 8}px`, + transform: "translateX(-50%)", ...style, } : (style ?? {})