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.
This commit is contained in:
@@ -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 ?? {})
|
||||
|
||||
Reference in New Issue
Block a user