Introducing PrimeReact v11-alpha 🎉Discover Now

useConfirmDialog

Hook that manages confirmation dialog overlays with icon, message, and action button support.

basic-demo

Usage#

import { useMotion } from '@primereact/core/motion';
import { useConfirmDialog } from '@primereact/headless/confirmdialog';
import { usePortal } from '@primereact/headless/portal';
import * as React from 'react';
import { createPortal } from 'react-dom';
const { rootProps, triggerProps, backdropProps, positionerProps, popupProps, closeProps, headerProps, contentProps } = useConfirmDialog();
const portal = usePortal();
 
<div {...rootProps}>
    <button {...triggerProps}></button>
    {portal.state.mounted &&
        createPortal(
            <>
                <div {...backdropProps} />
                <div {...positionerProps}>
                    <div {...popupProps}>
                        <div {...headerProps}>
                            <button {...closeProps}></button>
                        </div>
                        <div {...contentProps}>...</div>
                    </div>
                </div>
            </>,
            document.body

useConfirmDialog extends useDialog with a confirmation-oriented API. See Primitive for a component-based API.

Features#

  • Confirmation lifecycle — open/close state with backdrop dismissal, escape handling, and automatic focus on the primary action
  • Focus management — traps focus between Accept and Reject controls and restores it to the trigger on dismiss
  • Positioning — nine preset positions plus data-position for CSS-based layout variations
  • Scroll and layering — body scroll lock paired with baseZIndex/autoZIndex to stack above other overlays
  • Portal-ready — designed to pair with usePortal and createPortal for SSR-safe body portaling
  • Imperative controls — close() method and state.open flag for programmatic dismissal and conditional rendering

Working with callbacks#

Controlled open state#

Pass open and onOpenChange to drive visibility from external state — useful when the confirmation is triggered by business logic.

const [isOpen, setIsOpen] = React.useState(false);
 
const confirmdialog = useConfirmDialog({
    open: isOpen,
    onOpenChange: (e) => setIsOpen(e.value)
});

Accept and reject actions#

Wire the confirm flow by closing the dialog from both buttons and performing side effects in the handler.

const confirmdialog = useConfirmDialog();
 
const handleAccept = async () => {
    await deleteItem();
    confirmdialog.close();
};
 
<button onClick={handleAccept}>Yes</button>
<button {...confirmdialog.closeProps}>No</button>

Top-aligned layout#

Use the position prop when the confirmation should appear near the top of the viewport instead of centered.

const confirmdialog = useConfirmDialog({ position: 'top' });

Stacking with other overlays#

Combine baseZIndex with autoZIndex so each confirmation renders above the dialog that spawned it.

const confirmdialog = useConfirmDialog({ baseZIndex: 1200, autoZIndex: true });

Styling with data attributes#

The hook exposes state through data-* attributes on each part. Use them as CSS selectors — no className juggling.

ScopePartStates
confirmdialogrootdata-open, data-closed
confirmdialogpopupdata-open, data-closed
confirmdialogpositionerdata-position, data-scroll-behavior
[data-scope='confirmdialog'][data-part='positioner'] {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
 
[data-scope='confirmdialog'][data-part='positioner'][data-position='top'] {
    align-items: flex-start;
}

API#

useConfirmDialog#

NameTypeDefault
openboolean—
Specifies the visibility of the dialog.
defaultOpenboolean—
Specifies the default visibility of the dialog.
draggablebooleantrue
Enables dragging to change the position using header.
keepInViewportbooleantrue
Keeps dialog in the viewport.
trappedbooleantrue
When enabled, focus is trapped within the dialog (modal behavior).
modalbooleantrue
Whether the dialog is modal. When true, the positioner blocks pointer events behind it.
dismissablebooleanfalse
Specifies if clicking the modal background should hide the dialog.
closeOnEscapebooleantrue
Specifies if pressing escape key should hide the dialog.
blockScrollbooleanfalse
Whether background scroll should be blocked when dialog is visible.
baseZIndexnumber0
Base zIndex value to use in layering.
autoZIndexbooleantrue
Whether to automatically manage layering.
appendTo"body" | HTMLElement | "self"body
A valid query selector or an HTMLElement to specify where the dialog gets attached.
position"center" | "top" | "bottom" | "left" | "right" | "topleft" | "topright" | "bottomleft" | "bottomright"center
Position of the dialog.
fullScreenbooleanfalse
Whether the dialog should open in full screen (maximized) mode.
scrollBehavior"inside" | "outside"'inside'
Defines the scroll behavior of the dialog. When set to 'inside', the dialog content area scrolls. When set to 'outside', the positioner scrolls allowing the entire dialog to scroll within the viewport.
onOpenChange(event: useDialogChangeEvent) => void—
Callback function that is called when the trigger is clicked.

Accessibility#

Escape dismisses, Tab cycles between Accept and Reject buttons, and focus auto-moves into the dialog when it opens. See Primitive for full WAI-ARIA compliance details.