Skip to content

Commit e34c825

Browse files
committed
Hide preview overlay while popups are open
- Detect portal dropdown and popover positioners in the web UI - Suspend the native BrowserView overlay so menus render above it
1 parent bfe2af6 commit e34c825

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
@@ -38,6 +38,19 @@ const HIDDEN_PREVIEW_BOUNDS = {
3838
viewportHeight: 0,
3939
} as const;
4040

41+
/**
42+
* Selector that matches any popup positioner element portaled to the body.
43+
* When any of these are present, the native BrowserView overlay should be
44+
* hidden so it doesn't render on top of dropdown menus / popovers.
45+
*/
46+
const POPUP_POSITIONER_SELECTOR = [
47+
'[data-slot="menu-positioner"]',
48+
'[data-slot="popover-positioner"]',
49+
'[data-slot="select-positioner"]',
50+
'[data-slot="combobox-positioner"]',
51+
'[data-slot="autocomplete-positioner"]',
52+
].join(",");
53+
4154
function getActiveTab(state: PreviewTabsState): PreviewTabState | null {
4255
if (!state.activeTabId) return null;
4356
return state.tabs.find((t) => t.tabId === state.activeTabId) ?? null;
@@ -117,11 +130,15 @@ export function PreviewPanel({ threadId, onClose }: PreviewPanelProps) {
117130
if (!element) return HIDDEN_PREVIEW_BOUNDS;
118131

119132
const rect = element.getBoundingClientRect();
133+
// Hide the native BrowserView when any popup/dropdown is open so it
134+
// doesn't render on top of menus (native overlays ignore CSS z-index).
135+
const hasOpenPopup = document.querySelector(POPUP_POSITIONER_SELECTOR) !== null;
120136
const visible =
121137
tabsState.tabs.length > 0 &&
122138
document.visibilityState === "visible" &&
123139
rect.width > 0 &&
124-
rect.height > 0;
140+
rect.height > 0 &&
141+
!hasOpenPopup;
125142
return {
126143
x: rect.left,
127144
y: rect.top,
@@ -164,6 +181,11 @@ export function PreviewPanel({ threadId, onClose }: PreviewPanelProps) {
164181
lastBoundsKey = "";
165182
};
166183

184+
// Watch for popup positioners being added/removed from the DOM so we
185+
// can immediately hide/show the native BrowserView overlay.
186+
const popupObserver = new MutationObserver(invalidateBounds);
187+
popupObserver.observe(document.body, { childList: true, subtree: false });
188+
167189
window.addEventListener("resize", invalidateBounds);
168190
window.addEventListener("scroll", invalidateBounds, true);
169191
document.addEventListener("visibilitychange", invalidateBounds);
@@ -176,6 +198,7 @@ export function PreviewPanel({ threadId, onClose }: PreviewPanelProps) {
176198
destroyed = true;
177199
if (frameId !== 0) window.cancelAnimationFrame(frameId);
178200
resizeObserver?.disconnect();
201+
popupObserver.disconnect();
179202
window.removeEventListener("resize", invalidateBounds);
180203
window.removeEventListener("scroll", invalidateBounds, true);
181204
document.removeEventListener("visibilitychange", invalidateBounds);

0 commit comments

Comments
 (0)