Improve toolbar positioning to avoid keyboard obstruction

Update toolbar positioning logic to flip above the editor when necessary to prevent it from being hidden by the visual viewport or the software keyboard, addressing issue #581.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: fb6e8c2d-05ca-4eef-bd9b-dcf819bfcfcd
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/1WKAcHk
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
riyadhafraa
2026-05-18 08:30:20 +00:00
parent 7bb27527fb
commit 207bbb482c
@@ -545,9 +545,11 @@ function FormattingToolbar({
: "bg-white text-[#0B1E3F] hover:bg-gray-100 border border-gray-200");
// Position the toolbar via a portal so it escapes table cells with
// overflow:hidden. We try to place it above the editor, but flip below
// when there isn't enough room (e.g. first row of the table). We also
// clamp horizontally to keep it inside the viewport.
// overflow:hidden. Default placement is BELOW the editor; we only
// flip ABOVE when staying below would hide the toolbar under the iOS
// soft keyboard or off the bottom of the visible viewport (#581).
// We also clamp horizontally to keep it inside the table's scroll
// container (falling back to the viewport).
const [pos, setPos] = useState<{ top: number; left: number } | null>(null);
const [toolbarEl, setToolbarEl] = useState<HTMLDivElement | null>(null);
const setToolbarNode = useCallback(
@@ -595,7 +597,7 @@ function FormattingToolbar({
// swatches / Save / Cancel become unreachable on iPad. See #581.
const vvTop = vv.offsetTop;
const vvBottom =
vv.offsetTop + (vv.height || window.innerHeight);
vv.offsetTop + (vv.height ?? window.innerHeight);
let top = rect.bottom + 4;
if (top + tbHeight > vvBottom - 4) {
const above = rect.top - tbHeight - 4;