@@ -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+
5669const 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