usePortalContainer
Read the DOM element that portalled overlays (dialogs, popovers, tooltips) should render into.
Installation
npx shadcn@latest add @redpanda/use-portal-containerpnpm dlx shadcn@latest add @redpanda/use-portal-containeryarn dlx shadcn@latest add @redpanda/use-portal-containerbunx shadcn@latest add @redpanda/use-portal-containernubx shadcn@latest add @redpanda/use-portal-containeraube dlx shadcn@latest add @redpanda/use-portal-containerusePortalContainer reads the current portal target from context. Overlay components (Dialog, Popover, Tooltip, DropdownMenu, Select, and friends) call it so their floating content mounts inside a scoped container instead of document.body — essential when rendering inside a shadow root, a fullscreen element, or an iframe where body is the wrong root.
Wrap a subtree in PortalContainerProvider to override the target for everything inside it.
Usage
import { useRef } from "react";
import {
PortalContainerProvider,
usePortalContainer,
} from "@/hooks/use-portal-container";
function Scoped() {
const containerRef = useRef<HTMLDivElement>(null);
return (
<div ref={containerRef} className="relative">
<PortalContainerProvider value={containerRef.current ?? undefined}>
{/* Dialogs / popovers here portal into containerRef instead of body */}
<MyDialog />
</PortalContainerProvider>
</div>
);
}
// Inside an overlay component:
function MyOverlay() {
const container = usePortalContainer();
// pass `container` to the underlying portal
}
API
usePortalContainer()
Takes no arguments.
Returns HTMLElement | undefined — the nearest provided portal container, or undefined to fall back to the default (usually document.body).
PortalContainerProvider
A context provider. Set its value to the HTMLElement (or undefined) that descendants should portal into.