PrimeUI PRO for React is now available 🚀View Demos
styledOverlay

OverlayManager

OverlayManager opens overlay components imperatively from anywhere in your app.

preview

Usage#

import { createOverlayManager } from '@primereact/core/overlay-manager';

Declare a manager at module scope, pass a render function that spreads the injected props onto an overlay root, and mount <manager.Viewport /> once in your layout.

const dialog = createOverlayManager<{ title: string; description?: string }>(({ title, description, ...rest }) => (
    <Dialog.Root {...rest}>
        <Dialog.Portal>
            <Dialog.Backdrop />
            <Dialog.Positioner>
                <Dialog.Popup>
                    <Dialog.Header>
                        <Dialog.Title>{title}</Dialog.Title>
                    </Dialog.Header>
                    <Dialog.Content>{description}</Dialog.Content>
                </Dialog.Popup>
            </Dialog.Positioner>
        </Dialog.Portal>
    </Dialog.Root>
));

The render function receives the caller props merged with three injected lifecycle props, open, onOpenChange, and onExitComplete. Spreading them onto Dialog.Root lets the manager fully control open state, entry into the tree, and removal after the exit animation.

// Layout
<dialog.Viewport />;
 
// Anywhere
dialog.open({ title: 'Hello', description: 'World' });

API#

interface OverlayManagerInstance<P> {
    open: (props: P, id?: string) => string;
    close: (id?: string) => void;
    update: (id: string, props: Partial<P>) => void;
    Viewport: React.ComponentType;
}
  • open(props, id?), mounts a new entry with the given props. Returns the generated (or supplied) id.
  • close(id?), starts the close transition. Called with no id, every open entry is closed.
  • update(id, props), shallow-merges new props into an already-open entry. The mounted overlay re-renders in place.
  • Viewport, the component that renders every open entry. Mount once per manager.

Examples#

Basic#

Open a dialog imperatively with open() and close it via the close button or escape key.

basic-demo

Update#

Call update(id, partialProps) after open to change the mounted dialog's content without closing it.

update-demo

Stacked#

Multiple entries mount side by side. close() with no id begins closing every open entry, each one finishes its own exit animation independently.

stacked-demo

Confirm#

Pass user-defined callbacks (like onConfirm) as part of your payload, they remain available inside the render function.

confirm-demo

Drawer#

The same API works for any overlay component that accepts open / onOpenChange / onOpenChangeComplete, here a managed Drawer with configurable position.

drawer-demo

Popover#

Popovers need an anchor element. Pass a ref to it through the payload and read it inside the render function. Popover's onOpenChange uses { open } instead of { value }, so the render function bridges the two.

popover-demo

Tooltip#

Tooltip accepts an anchor prop for imperative use, just like Popover. Opening a tooltip from a click doesn't feel native, prefer Popover or Toast for click-driven flows, but the plumbing works identically when you need it.

tooltip-demo