Mosmox UI
Current version
GitHubnpmjs.com
Overlays

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 ConfirmationDialog and control it with open/onOpenChange or defaultOpen;
  • programmatic — mount ConfirmationDialogProvider once and call confirm() 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 Dialog and 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 closeOnOverlayClick only when cancellation is safe.
  • Provide a meaningful title, description, or explicit aria-label so the purpose is clear to assistive technology.
  • Use intent="danger" for destructive actions and make the confirm label explicit, such as Delete workspace instead of OK.

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

PropertyTypeDefaultDescription
titleReactNodelocalized questionDialog heading.
descriptionReactNode—Supporting explanation.
childrenReactNode—Custom body content.
aria-labelstringtitle/questionAccessible name when the visible heading is not sufficient.
idstringgeneratedStable dialog id.
footerAsideReactNode—Additional footer content displayed opposite the actions.
confirmLabelReactNodelocalized OKConfirm action label.
cancelLabelReactNodelocalized CancelCancel action label.
confirmIconReactNodeCheck iconConfirm action icon.
cancelIconReactNodeX iconCancel action icon.
intentdefault | warning | dangerdefaultConfirm button and header icon treatment.
onConfirm() => void | Promise<void>—Confirmation callback.
onCancel() => void—Cancellation callback.
openboolean—Controlled open state.
defaultOpenbooleanfalseInitial uncontrolled state.
onOpenChange(open) => void—Open state callback.
closeOnConfirmbooleantrueCloses after successful confirmation.
closeButtonbooleantrueShows header close button, which counts as cancel.
closeOnOverlayClickbooleanfalseAllows overlay click to cancel.
confirmLoadingbooleanfalseControlled loading state for the confirm action.
confirmDisabledbooleanfalseDisables confirmation.
cancelDisabledbooleanfalseDisables cancellation action.
localeen | uk | fr | deprovider localeLocalized default strings.
sizexs | sm | default | lg | xl | fullsmDialog size.
widthnumber | stringcurrent default widthCustom 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

ExportSignatureDescription
ConfirmationDialogProvider({ children }) => ReactNodeMount 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 keyTypeDescription
confirmationDialog.intentdefault | warning | dangerDefault semantic intent.
confirmationDialog.confirmLabelstringDefault confirm button label.
confirmationDialog.cancelLabelstringDefault cancel button label.
confirmationDialog.closeButtonbooleanDefault visibility of the header close button.
confirmationDialog.closeOnOverlayClickbooleanDefault overlay dismissal behavior.
confirmationDialog.sizexs | sm | default | lg | xl | fullDefault 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.