// Where menus, dialogs, sheets and tooltips portal to. A page that owns the // document (the web app) leaves it unset, so they portal to as Radix // does by default. An embedded app sets its own root, so its overlays stay // inside the scoped stylesheet and carry the app's theme, not the host page's. import { createContext, useContext, type ComponentType, type ReactNode } from "react"; type PortalTarget = Element | DocumentFragment; const PortalContainerContext = createContext(null); export function PortalContainerProvider(props: { container: PortalTarget | null; children?: ReactNode; }) { return ( {props.children} ); } /** The provided portal target, or null for . */ export function usePortalContainer(): PortalTarget | null { return useContext(PortalContainerContext); } type PortalProps = { container?: PortalTarget | null | undefined; children?: ReactNode }; /** A Radix `Portal` that targets the provided container unless given its own. */ export function containedPortal

(Portal: ComponentType

): ComponentType

{ function ContainedPortal(props: P) { const container = usePortalContainer(); return ; } ContainedPortal.displayName = `Contained(${Portal.displayName ?? Portal.name ?? "Portal"})`; return ContainedPortal; }