Skip to content

Commit f43f959

Browse files
authored
Hide preview overlay while popups are open (#110) (#114)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent cc57b57 commit f43f959

1 file changed

Lines changed: 24 additions & 1 deletion

File tree

apps/web/src/components/PreviewPanel.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@ const HIDDEN_PREVIEW_BOUNDS = {
5353
viewportHeight: 0,
5454
} as const;
5555

56+
/**
57+
* Selector that matches any popup positioner element portaled to the body.
58+
* When any of these are present, the native BrowserView overlay should be
59+
* hidden so it doesn't render on top of dropdown menus / popovers.
60+
*/
61+
const POPUP_POSITIONER_SELECTOR = [
62+
'[data-slot="menu-positioner"]',
63+
'[data-slot="popover-positioner"]',
64+
'[data-slot="select-positioner"]',
65+
'[data-slot="combobox-positioner"]',
66+
'[data-slot="autocomplete-positioner"]',
67+
].join(",");
68+
5669
const PRESET_ICONS: Record<BrowserPresetId, typeof SmartphoneIcon> = {
5770
mobile: SmartphoneIcon,
5871
tablet: TabletIcon,
@@ -147,11 +160,15 @@ export function PreviewPanel({ threadId, onClose }: PreviewPanelProps) {
147160
if (!element) return HIDDEN_PREVIEW_BOUNDS;
148161

149162
const rect = element.getBoundingClientRect();
163+
// Hide the native BrowserView when any popup/dropdown is open so it
164+
// doesn't render on top of menus (native overlays ignore CSS z-index).
165+
const hasOpenPopup = document.querySelector(POPUP_POSITIONER_SELECTOR) !== null;
150166
const visible =
151167
tabsState.tabs.length > 0 &&
152168
document.visibilityState === "visible" &&
153169
rect.width > 0 &&
154-
rect.height > 0;
170+
rect.height > 0 &&
171+
!hasOpenPopup;
155172
return {
156173
x: rect.left,
157174
y: rect.top,
@@ -194,6 +211,11 @@ export function PreviewPanel({ threadId, onClose }: PreviewPanelProps) {
194211
lastBoundsKey = "";
195212
};
196213

214+
// Watch for popup positioners being added/removed from the DOM so we
215+
// can immediately hide/show the native BrowserView overlay.
216+
const popupObserver = new MutationObserver(invalidateBounds);
217+
popupObserver.observe(document.body, { childList: true, subtree: false });
218+
197219
window.addEventListener("resize", invalidateBounds);
198220
window.addEventListener("scroll", invalidateBounds, true);
199221
document.addEventListener("visibilitychange", invalidateBounds);
@@ -206,6 +228,7 @@ export function PreviewPanel({ threadId, onClose }: PreviewPanelProps) {
206228
destroyed = true;
207229
if (frameId !== 0) window.cancelAnimationFrame(frameId);
208230
resizeObserver?.disconnect();
231+
popupObserver.disconnect();
209232
window.removeEventListener("resize", invalidateBounds);
210233
window.removeEventListener("scroll", invalidateBounds, true);
211234
document.removeEventListener("visibilitychange", invalidateBounds);

0 commit comments

Comments
 (0)