Skip to content

Commit e6a14f2

Browse files
committed
fix(popover): update layering of popover component relative to other components
1 parent 7092b81 commit e6a14f2

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

core/components/atoms/popperWrapper/PopperWrapper.tsx

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import {
2020
safePolygon,
2121
} from '@floating-ui/react';
2222
import { createStyleFromClass } from './utils';
23+
import OverlayManager from '@/utils/OverlayManager';
24+
import { getWrapperElement, getUpdatedZIndex } from '@/utils/overlayHelper';
2325

2426
export interface PopperWrapperProps {
2527
initialOpen?: boolean;
@@ -227,6 +229,9 @@ export const PopoverContent = React.forwardRef<HTMLDivElement, React.HTMLProps<H
227229
) {
228230
const { context: floatingContext, ...context } = usePopoverContext();
229231
const ref = useMergeRefs([context.refs.setFloating, propRef]);
232+
const popoverRef = React.useRef<HTMLDivElement | null>(null);
233+
const mergedRef = useMergeRefs([ref, popoverRef]);
234+
const [zIndex, setZIndex] = React.useState<number | undefined>(undefined);
230235

231236
// if (!floatingContext.open) return null;
232237

@@ -258,6 +263,56 @@ export const PopoverContent = React.forwardRef<HTMLDivElement, React.HTMLProps<H
258263
hasValidPositionRef.current = false;
259264
}
260265

266+
// Integrate with OverlayManager for proper layering with other components
267+
React.useEffect(() => {
268+
if (!context.open || !popoverRef.current) {
269+
if (popoverRef.current) {
270+
OverlayManager.remove(popoverRef.current);
271+
setZIndex(undefined);
272+
}
273+
return;
274+
}
275+
276+
// Register with OverlayManager
277+
OverlayManager.add(popoverRef.current);
278+
279+
// Calculate z-index: find max z-index among all overlay elements
280+
const calculateZIndex = () => {
281+
if (!popoverRef.current || typeof document === 'undefined') return;
282+
283+
// First try using existing helper for Overlay-container elements
284+
const overlayWrapper = getWrapperElement();
285+
let maxZIndex = getUpdatedZIndex({
286+
element: overlayWrapper,
287+
containerClassName: '.Overlay-container--open',
288+
elementRef: { current: popoverRef.current },
289+
});
290+
291+
// Also check all overlay elements in document.body (comprehensive fallback)
292+
const allOverlays = document.querySelectorAll('[data-layer="true"], .Overlay-container--open');
293+
allOverlays.forEach((element) => {
294+
if (element !== popoverRef.current) {
295+
const zIndexValue = parseInt(window.getComputedStyle(element).zIndex || '0', 10);
296+
if (zIndexValue > 0) {
297+
maxZIndex = Math.max(maxZIndex || 0, zIndexValue);
298+
}
299+
}
300+
});
301+
302+
// Set z-index if found, otherwise undefined (uses default CSS)
303+
setZIndex(maxZIndex && maxZIndex > 0 ? maxZIndex + 10 : undefined);
304+
};
305+
306+
// Calculate after DOM update
307+
requestAnimationFrame(calculateZIndex);
308+
309+
return () => {
310+
if (popoverRef.current) {
311+
OverlayManager.remove(popoverRef.current);
312+
}
313+
};
314+
}, [context.open]);
315+
261316
// Determine if we should show the content
262317
const canShow = hasReference && ((isValidPosition && hasCalculatedPosition) || hasValidPositionRef.current);
263318
const shouldHide = context.middlewareData.hide?.referenceHidden || context.middlewareData.hide?.escaped || !canShow;
@@ -267,10 +322,11 @@ export const PopoverContent = React.forwardRef<HTMLDivElement, React.HTMLProps<H
267322
// // modal={context.modal}
268323
// initialFocus={-1}>
269324
<div
270-
ref={ref}
325+
ref={mergedRef}
271326
style={{
272327
...context.floatingStyles,
273328
...style,
329+
zIndex: zIndex,
274330
visibility: shouldHide ? 'hidden' : 'visible',
275331
// Completely hide when position is not ready to prevent (0,0) flash
276332
opacity: canShow ? undefined : 0,

0 commit comments

Comments
 (0)