fix(web): lock body scroll while modal is open

Native <dialog> in iOS Safari (and a few other browsers) doesn't
prevent the page underneath from scrolling when the user scrolls
inside the dialog or near its edges. Save and restore body overflow
on open/close so the background stays put. Stays correct for stacked
dialogs because we save the previous value rather than blanket-reset
to ''.
This commit is contained in:
yiekheng 2026-05-03 08:12:35 +08:00
parent 48dacdb445
commit 6c984b6200
2 changed files with 23 additions and 0 deletions

View File

@ -41,6 +41,19 @@ export default function ConfirmDialog({
} }
}, [open]); }, [open]);
// Lock body scroll while open. Native <dialog> doesn't do this in all
// browsers (notably iOS Safari), so background scroll can leak through
// when scrolling on the dialog content. We restore the previous value
// on close so other modals stacking later don't regress this.
useEffect(() => {
if (!open) return;
const previous = document.body.style.overflow;
document.body.style.overflow = "hidden";
return () => {
document.body.style.overflow = previous;
};
}, [open]);
return ( return (
<dialog <dialog
ref={ref} ref={ref}

View File

@ -40,6 +40,16 @@ export default function FormDialogShell({
else if (!open && dialog.open) dialog.close(); else if (!open && dialog.open) dialog.close();
}, [open]); }, [open]);
// Lock body scroll while open (native <dialog> doesn't on iOS Safari).
useEffect(() => {
if (!open) return;
const previous = document.body.style.overflow;
document.body.style.overflow = "hidden";
return () => {
document.body.style.overflow = previous;
};
}, [open]);
return ( return (
<dialog <dialog
ref={ref} ref={ref}