Confirmation Dialog
A localized dialog for confirming important or destructive actions.
ConfirmationDialog is a focused confirmation flow built on the framework Dialog. It provides a question, optional description and custom content, Cancel and OK actions, a close button treated as cancellation, intent styling, asynchronous confirmation loading, and controlled or uncontrolled state.
Use it when an action needs an explicit decision before it continues, especially for destructive, irreversible, permission-changing, or publishing operations. It is modal: the page behind it cannot be used until the dialog is confirmed or cancelled.
The component is available in two modes:
- declarative — render
ConfirmationDialogand control it withopen/onOpenChangeordefaultOpen; - programmatic — mount
ConfirmationDialogProvideronce and callconfirm()from application code.
Basic usage
<ConfirmationDialog
open={open}
onOpenChange={setOpen}
title="Delete this draft?"
description="This action cannot be undone."
onConfirm={() => deleteDraft()}
/>The default actions are OK and Cancel, with Check and X icons. The header close button is enabled by default and is treated exactly like Cancel.
Custom width
The default width remains the component's standard width. Use width when a flow needs a narrower or wider dialog. Numbers are interpreted as pixels; strings can use any valid CSS width value.
<ConfirmationDialog
open={open}
onOpenChange={setOpen}
width={560}
title="Custom-width confirmation"
description="This dialog is 560px wide."
onConfirm={saveChanges}
/><ConfirmationDialog width="min(90vw, 640px)" title="Responsive confirmation" />Custom labels, icons, and content
<ConfirmationDialog
intent="danger"
title="Remove workspace?"
description="All members will lose access."
confirmLabel="Remove workspace"
cancelLabel="Keep workspace"
confirmIcon={<Trash2 size={16} />}
cancelIcon={<ArrowLeft size={16} />}
onConfirm={removeWorkspace}
>
<p>Export any data you need before continuing.</p>
</ConfirmationDialog>Use intent="warning" for risky but recoverable actions and intent="danger" for destructive actions. title, description, children, labels, and icons accept React nodes where custom content is needed.
Complex body content
Pass any React node through children when the confirmation needs more than a short message. The dialog keeps its standard Cancel and OK actions while the body can contain another component, such as ActivityFeed.
const activity = [
{
key: 'deployment',
title: 'Deployment completed',
actor: 'Maya Chen',
timestamp: '10:42',
description: 'Version 2.4.0 is now running.',
status: 'success',
},
{
key: 'comment',
title: 'New comment on Project Atlas',
actor: 'Alex Morgan',
timestamp: '09:18',
description: 'The onboarding flow is ready for review.',
status: 'default',
},
];
<ConfirmationDialog
open={open}
onOpenChange={setOpen}
title="Review recent activity"
description="Check the latest workspace events before continuing."
>
<ActivityFeed
aria-label="Recent workspace activity"
items={activity}
size="sm"
variant="compact"
showConnector
/>
</ConfirmationDialog>children is rendered in the dialog body and accepts any ReactNode: text, forms, lists, Activity Feed, Profile Menu, or a custom layout. For long content, the body scrolls independently while the confirmation actions remain available.
Programmatic API
Wrap the application or the relevant feature in ConfirmationDialogProvider, then use useConfirmationDialog to open a dialog without rendering a dialog at the call site. confirm returns a Promise that resolves to true for confirmation and false for cancellation.
function DeleteButton() {
const { confirm } = useConfirmationDialog();
const handleDelete = async () => {
const confirmed = await confirm({
title: 'Delete this draft?',
description: 'This action cannot be undone.',
intent: 'danger',
confirmLabel: 'Delete draft',
cancelLabel: 'Keep draft',
width: 480,
});
if (confirmed) await deleteDraft();
};
return <Button onClick={() => void handleDelete()}>Delete draft</Button>;
}
function App() {
return (
<ConfirmationDialogProvider>
<DeleteButton />
</ConfirmationDialogProvider>
);
}The provider queues requests and displays one dialog at a time. Programmatic options support the same title, description, intent, labels, icons, children, width, async onConfirm, disabled/loading state, locale, and dismissal settings as the declarative component. If onConfirm rejects, the returned Promise rejects and the dialog is removed.
Async confirmation
onConfirm may return a Promise. The confirm button enters a loading state until the Promise resolves. The dialog closes after a successful confirmation when closeOnConfirm is enabled.
<ConfirmationDialog
open={open}
onOpenChange={setOpen}
title="Publish changes?"
onConfirm={async () => {
await publishChanges();
}}
closeOnConfirm
/>If the Promise rejects, the dialog remains open and the error can be handled by the application around the onConfirm callback.
Localization
Default labels and the default question/close label use the active ConfigProvider locale: en, uk, fr, or de. Set locale on one dialog to override the provider for that instance. Explicit confirmLabel, cancelLabel, and content always take precedence.
<ConfigProvider locale="uk">
<ConfirmationDialog
title="Опублікувати зміни?"
description="Зміни стануть доступними для всіх користувачів."
/>
</ConfigProvider>Controlled and uncontrolled modes
Use open and onOpenChange when the parent owns state. Use defaultOpen for an initially open uncontrolled dialog. onCancel fires when Cancel, the header close button, Escape, or an allowed overlay click closes the dialog.
When closeOnConfirm={false}, the confirm callback still runs and the dialog remains open. This is useful for multi-step flows or when the callback updates the dialog content instead of finishing the flow. When a confirm callback is asynchronous, the confirm button is disabled and shows its loading state until it settles.
Accessibility and interaction
- The dialog uses the modal semantics provided by
Dialogand restores focus when it closes. - The header close button is labelled from the active locale and is treated as cancellation.
- Escape and overlay dismissal are disabled by default; enable
closeOnOverlayClickonly when cancellation is safe. - Provide a meaningful
title,description, or explicitaria-labelso the purpose is clear to assistive technology. - Use
intent="danger"for destructive actions and make the confirm label explicit, such asDelete workspaceinstead ofOK.
Sizes and width
The default component size is sm. Its standard sm presentation is compact; the current default width is 320px. Other Dialog sizes can be selected with size, while width overrides the CSS width for that instance. A numeric width is converted to pixels. A string is passed as a CSS width value and can use responsive functions such as min() or calc().
API reference
| Property | Type | Default | Description |
|---|---|---|---|
title | ReactNode | localized question | Dialog heading. |
description | ReactNode | — | Supporting explanation. |
children | ReactNode | — | Custom body content. |
aria-label | string | title/question | Accessible name when the visible heading is not sufficient. |
id | string | generated | Stable dialog id. |
footerAside | ReactNode | — | Additional footer content displayed opposite the actions. |
confirmLabel | ReactNode | localized OK | Confirm action label. |
cancelLabel | ReactNode | localized Cancel | Cancel action label. |
confirmIcon | ReactNode | Check icon | Confirm action icon. |
cancelIcon | ReactNode | X icon | Cancel action icon. |
intent | default | warning | danger | default | Confirm button and header icon treatment. |
onConfirm | () => void | Promise<void> | — | Confirmation callback. |
onCancel | () => void | — | Cancellation callback. |
open | boolean | — | Controlled open state. |
defaultOpen | boolean | false | Initial uncontrolled state. |
onOpenChange | (open) => void | — | Open state callback. |
closeOnConfirm | boolean | true | Closes after successful confirmation. |
closeButton | boolean | true | Shows header close button, which counts as cancel. |
closeOnOverlayClick | boolean | false | Allows overlay click to cancel. |
confirmLoading | boolean | false | Controlled loading state for the confirm action. |
confirmDisabled | boolean | false | Disables confirmation. |
cancelDisabled | boolean | false | Disables cancellation action. |
locale | en | uk | fr | de | provider locale | Localized default strings. |
size | xs | sm | default | lg | xl | full | sm | Dialog size. |
width | number | string | current default width | Custom dialog width. Numbers use px; strings are passed as CSS width values. |
onOpenChange receives visibility changes. onCancel is called for Cancel, the header close button, Escape, or an allowed overlay click. onConfirm is called only after the confirm action is activated; if it returns a rejected Promise, the dialog remains open in declarative mode.
Programmatic API reference
| Export | Signature | Description |
|---|---|---|
ConfirmationDialogProvider | ({ children }) => ReactNode | Mount once above features that call the API. Requests are displayed sequentially. |
useConfirmationDialog | () => { confirm } | Returns the imperative dialog controller. Must be used inside the provider. |
confirm | (options) => Promise<boolean> | Opens a dialog; resolves true on confirmation and false on cancellation. |
Programmatic confirm accepts the component options except controlled lifecycle props (open, defaultOpen, and onOpenChange). The provider owns those values, queues concurrent requests, and removes a rejected request after rejecting its Promise.
ConfigProvider and tokens
<ConfigProvider components={{
confirmationDialog: {
intent: 'warning',
confirmLabel: 'Continue',
cancelLabel: 'Go back',
closeOnOverlayClick: false,
size: 'default',
},
}}>
<ConfirmationDialog title="Continue setup?" />
</ConfigProvider>| ConfigProvider key | Type | Description |
|---|---|---|
confirmationDialog.intent | default | warning | danger | Default semantic intent. |
confirmationDialog.confirmLabel | string | Default confirm button label. |
confirmationDialog.cancelLabel | string | Default cancel button label. |
confirmationDialog.closeButton | boolean | Default visibility of the header close button. |
confirmationDialog.closeOnOverlayClick | boolean | Default overlay dismissal behavior. |
confirmationDialog.size | xs | sm | default | lg | xl | full | Default Dialog size. |
The component uses the shared Dialog, Button, color, typography, radius, focus, overlay, and spacing tokens. Override tokens through ConfigProvider.theme or a scoped CSS theme without changing the component API.