Fix dialog display issues when the on-screen keyboard is active

Adjust dialog positioning on iOS Safari to render as a full-width sheet when the keyboard is open, preventing layout shifts and ensuring content remains visible.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: b9f9a662-72a9-4295-a75e-826dc00f7f90
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
This commit is contained in:
riyadhafraa
2026-05-20 14:10:41 +00:00
parent 98a07daa35
commit 01adae003e
+23 -14
View File
@@ -41,23 +41,32 @@ const DialogContent = React.forwardRef<
const keyboardOpen = keyboardInset > 80
const dynamicStyle: React.CSSProperties = keyboardOpen
? {
// 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.
// Mobile-sheet behaviour when an on-screen keyboard is open.
//
// 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.
// The base className puts the dialog at left:50%+translateX(-50%)
// (horizontal centering) and top:50%+translateY(-50%) (vertical
// centering). On iOS Safari with the soft keyboard open the
// layout viewport and the visual viewport diverge in BOTH axes
// (visualViewport.offsetLeft, .pageLeft and zoom factor can all
// shift), which made our previous "top-anchor + translateX(-50%)"
// override render as a narrow column shoved against one edge of
// the screen.
//
// To sidestep all of that we drop the centering entirely while
// the keyboard is open and pin the dialog as a top-anchored
// full-width sheet: explicit left/right insets, no transform,
// width:auto so the consumer's `w-[calc(100vw-1rem)]` or
// `max-w-3xl` no longer drive horizontal position. The
// dialog's internal `flex flex-col` (header / scrollable middle
// / sticky footer) then keeps Save/Cancel pinned above the
// keyboard and the rest of the form scrolls inside.
top: `${offsetTop}px`,
left: "8px",
right: "8px",
width: "auto",
maxWidth: "none",
maxHeight: `${height - 8}px`,
transform: "translateX(-50%)",
transform: "none",
...style,
}
: (style ?? {})