ui: prevent layout shift when mobile search overlay opens
- SearchPanel: focus input with { preventScroll: true } so the browser
doesn't auto-scroll the underlying page when the overlay mounts.
- SearchPanel: add overscroll-contain on the scroll container so
reaching the panel's edges does not chain into the body on Android.
- PublicLayout: lock background scroll while the mobile search overlay
is open using the iOS-compatible position-fixed + restore pattern,
so the page underneath cannot move at all.
This commit is contained in:
@@ -331,6 +331,35 @@ export function PublicLayout() {
|
||||
};
|
||||
}, [open]);
|
||||
|
||||
// Lock background scroll while the mobile search overlay is open.
|
||||
// Uses the iOS-compatible position-fixed pattern so the underlying page
|
||||
// doesn't move at all (overflow:hidden alone is not enough on iOS Safari).
|
||||
useEffect(() => {
|
||||
if (!mobileSearchOpen) return;
|
||||
const scrollY = window.scrollY;
|
||||
const body = document.body;
|
||||
const prev = {
|
||||
position: body.style.position,
|
||||
top: body.style.top,
|
||||
left: body.style.left,
|
||||
right: body.style.right,
|
||||
width: body.style.width,
|
||||
};
|
||||
body.style.position = "fixed";
|
||||
body.style.top = `-${scrollY}px`;
|
||||
body.style.left = "0";
|
||||
body.style.right = "0";
|
||||
body.style.width = "100%";
|
||||
return () => {
|
||||
body.style.position = prev.position;
|
||||
body.style.top = prev.top;
|
||||
body.style.left = prev.left;
|
||||
body.style.right = prev.right;
|
||||
body.style.width = prev.width;
|
||||
window.scrollTo(0, scrollY);
|
||||
};
|
||||
}, [mobileSearchOpen]);
|
||||
|
||||
return (
|
||||
<div className="min-h-full flex flex-col">
|
||||
<DocumentMeta />
|
||||
|
||||
Reference in New Issue
Block a user