Gecko UIGecko UI

ConfirmDialog

Confirmation modal for user action validation

You are reading the v1 docs. v2 renamed several props and replaced GeckoUIPortal with GeckoUIProvider. Read this page in v2.

Live examples are only rendered in the v2 docs.

ConfirmDialog

ConfirmDialog is a flexible confirmation modal component that prompts users for action validation. Built on top of the Dialog component, it provides a standardized interface for displaying confirmation prompts with customizable content, buttons, and behavior.

Installation

import { ConfirmDialog } from '@geckoui/geckoui';

Basic Usage

ConfirmDialog.show({
  title: "Confirm Action",
  content: "Are you sure you want to proceed?",
  onConfirm: () => {
    console.log('Confirmed');
  }
});

API Reference

ConfirmDialog.show(options)

OptionTypeDefaultDescription
titlestring-Dialog title
contentReactNode | FC<{dismiss}>-Dialog content
confirmButtonLabelstring'Ok'Confirm button text
cancelButtonLabelstring'Cancel'Cancel button text
onConfirm(args) => void | Promise<void>-Confirm callback
onCancel(args) => void | Promise<void>-Cancel callback
classNamestring-CSS class for dialog
titleClassNamestring-CSS class for title
contentClassNamestring-CSS class for content
dismissOnEscbooleanfalseClose on Escape key
dismissOnOutsideClickbooleanfalseClose on outside click

Callback Arguments

Both onConfirm and onCancel receive an object with:

ArgumentTypeDescription
preventDefault() => voidPrevent auto-close
dismiss() => voidManually close dialog

ConfirmDialog.dismiss()

Programmatically closes the confirm dialog from anywhere in your app.

Examples

Delete Confirmation(Async)

function DeleteButton({ itemId }) {
  const handleDelete = () => {
    ConfirmDialog.show({
      title: "Delete Item",
      content: "Are you sure you want to delete this item? This action cannot be undone.",
      confirmButtonLabel: "Delete",
      cancelButtonLabel: "Cancel",
      onConfirm: async () => {
        await deleteItem(itemId);
        showSuccessMessage("Item deleted successfully");
      },
      onCancel: () => {
        console.log('Deletion cancelled');
      }
    });
  };

  return <button onClick={handleDelete}>Delete</button>;
}

If you declare onConfirm as an async function, the dialog shows a loading state on the confirm button until the promise resolves. In v1 onCancel is not awaited, so it never shows one.

Rich Content

ConfirmDialog.show({
  title: "Transfer Ownership",
  content: ({ dismiss }) => (
    <div className="space-y-4">
      <p>Transfer project ownership to:</p>
      <UserSelector onSelect={setSelectedUser} />
      <button onClick={dismiss} className="text-sm text-blue-500">
        Cancel transfer
      </button>
    </div>
  ),
  confirmButtonLabel: "Transfer Now",
  cancelButtonLabel: "Go Back",
  titleClassName: "text-warning",
  contentClassName: "min-h-[200px]",
  onConfirm: ({ dismiss }) => {
    performTransfer();
    dismiss();
  }
});

Custom Styling

ConfirmDialog.show({
  title: "Premium Feature",
  content: "This feature requires a premium subscription. Would you like to upgrade?",
  confirmButtonLabel: "Upgrade Now",
  cancelButtonLabel: "Maybe Later",
  className: "max-w-lg",
  titleClassName: "text-2xl font-bold text-purple-600",
  contentClassName: "text-gray-600 text-center py-6",
  onConfirm: () => {
    router.push("/upgrade");
  }
});

Behavior

Auto-Close

By default, the dialog automatically closes after:

  • Clicking confirm button (after onConfirm completes)
  • Clicking cancel button (after onCancel completes)

Manual Control

Use preventDefault() to prevent auto-close and handle dismissal manually:

onConfirm: async ({ preventDefault, dismiss }) => {
  preventDefault(); // Don't auto-close

  const result = await performOperation();

  if (result.success) {
    dismiss(); // Manually close
  }
  // Keep open if failed
}

Loading States

When onConfirm is declared async, the dialog automatically:

  • Awaits the Promise
  • Shows loading spinner on the button
  • Closes after completion

The check looks at the function declaration, not at what it returns, so a function that returns a promise without the async keyword gets no loading state.

onConfirm: async () => {
  await longRunningOperation();
}

To skip the loading indicator while still calling an async function:

onConfirm: () => {
  myAsyncFunction();
}

Keyboard Support

  • Enter: Triggers confirm action (when no focusable elements have focus)
  • Escape: Disabled by default (set dismissOnEsc: true to enable)

Accessibility

  • Built on Dialog component with full accessibility
  • Proper ARIA attributes
  • Keyboard navigation
  • Focus management
  • Loading states communicated to screen readers

Styling

  • GeckoUIConfirmDialog__dialog - Dialog container
  • GeckoUIConfirmDialog__title - Title element
  • GeckoUIConfirmDialog__content - Content wrapper
  • GeckoUIConfirmDialog__actions - Button container
  • GeckoUIConfirmDialog__confirm-button - Confirm button
  • GeckoUIConfirmDialog__cancel-button - Cancel button

Dependencies

This component uses:

  • Dialog component for modal functionality
  • LoadingButton for action buttons with loading states