From 65bfe32e60cd509029e73ee617b6d9ddc9f5b90e Mon Sep 17 00:00:00 2001 From: riyadhafraa <49757212-riyadhafraa@users.noreply.replit.com> Date: Mon, 25 May 2026 11:36:29 +0000 Subject: [PATCH] Task #634: fix SendNoteDialog centering on iPad PWA with keyboard open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-reported regression from #630: opening "Send note" on iPad PWA showed the recipient list pushed to the left side of the screen, narrower than designed, with the dialog title + search input clipped off the top. Dismissing the keyboard restored normal centered layout. Root cause: the `keyboardFallback` branch (iPad PWA, where visualViewport doesn't update) set `top: "6vh"` in *layout viewport* coordinates. On iPad PWA Safari, opening the keyboard scrolls the page down behind the keyboard, so layout-viewport `6vh` ends up above the visible visual viewport — clipping the top half of the dialog. Separately, the inline `transform` replaced Tailwind's translate-x/y on Radix's content, and without an explicit `left:50%` the animation/RTL combination shifted the box left. Fix (artifacts/tx-os/src/components/notes/send-note-dialog.tsx): - `keyboardFallback`: `top: calc(${vv.offsetTop || 0}px + 6vh)` so the anchor follows the visible visual viewport when Safari scrolls the page behind the keyboard. Add explicit `left: 50%`. Add `overflowY: auto` so if dialog content exceeds 50dvh, the dialog scrolls internally instead of clipping the header. - `keyboardActive` branch: also add explicit `left: 50%` defensively for the same animation/RTL reason (no behavior change on devices where it was already working, but eliminates the asymmetry). No changes to the shared `dialog.tsx`, composer, or executive-meetings dialog — scope strictly limited to the regression site. TypeScript: clean. Pre-existing errors in api-server/src/routes/push.ts unrelated to this diff. --- .../src/components/notes/send-note-dialog.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/artifacts/tx-os/src/components/notes/send-note-dialog.tsx b/artifacts/tx-os/src/components/notes/send-note-dialog.tsx index 9738c0ae..cf9d4c05 100644 --- a/artifacts/tx-os/src/components/notes/send-note-dialog.tsx +++ b/artifacts/tx-os/src/components/notes/send-note-dialog.tsx @@ -162,14 +162,31 @@ export function SendNoteDialog({ const dialogStyle: React.CSSProperties | undefined = keyboardActive ? { top: vv.offsetTop + vv.height / 2 - KEYBOARD_PREDICTION_INSET, + left: "50%", transform: "translate(-50%, -50%)", transition: "top 120ms ease", } : keyboardFallback ? { - top: "6vh", + // #634: bind `top` to `visualViewport.offsetTop` so when iPad + // PWA Safari scrolls the layout viewport down behind the + // soft keyboard, our top anchor follows the visible area + // instead of landing above it (which previously hid the + // dialog title + search input). + top: `calc(${vv.offsetTop || 0}px + 6vh)`, + // #634: pin `left: 50%` explicitly. Radix already sets it + // via Tailwind, but the inline `transform` below replaces + // Tailwind's `translate-x-[-50%] translate-y-[-50%]` so we + // also restate the horizontal anchor to defend against any + // animation/RTL interplay that was shifting the box left. + left: "50%", transform: "translate(-50%, 0)", maxHeight: "50dvh", + // #634: allow the dialog itself to scroll when its content + // is taller than the cap — otherwise the header could be + // clipped while only the bottom of the list/buttons stayed + // visible. + overflowY: "auto", transition: "top 120ms ease, transform 120ms ease", } : undefined;