import { SidePanelModal } from './SidePanelModal'; import React, { CSSProperties, RefObject, useEffect, useMemo, useState, } from 'react'; import { createPortal } from 'react-dom'; import { useWixPatternsContainer } from '@wix/bex-core/react'; import { addResizeObserver } from '@wix/bex-core'; import { SidePanelsState } from '../state/SidePanelsState'; export interface WixPatternsModalsContainerProps { rootRef?: RefObject; anchorRef?: RefObject; zIndex?: CSSProperties['zIndex']; state: SidePanelsState; } export function WixPatternsModalsContainer( props: WixPatternsModalsContainerProps, ) { const { state, rootRef, anchorRef, zIndex = 1 } = props; const { appendModalsToBody, lodash, useRelativeSidePanel } = useWixPatternsContainer(); const [render, setRender] = useState<{ top?: number; left?: number; anchor?: HTMLElement | null; }>({}); useEffect(() => { const { container, top } = appendModalsToBody ? { container: document.body, top: 0, } : { container: rootRef?.current ?? document.body, top: null, }; const setTop = lodash.throttle(() => { const id = window.requestAnimationFrame(() => { setRender({ top: top != null ? top : container.getBoundingClientRect().top, left: container.getBoundingClientRect().right, anchor: anchorRef?.current ?? container, }); }); disposers.push(() => window.cancelAnimationFrame(id)); }, 300); const disposers = [addResizeObserver(container, setTop)]; setTop(); return () => { setTop.cancel(); disposers.forEach((d) => d?.()); }; }, []); // creates a new stacking context const modalsContainerStyle = useMemo( () => ({ position: 'relative' as const, zIndex, }), [zIndex], ); let child = render.top != null && ( ); if (!useRelativeSidePanel) { child = (
{child}
); } if (render.anchor == null) { return null; } child = createPortal(child, render.anchor); return child; }