confirm()
Use it to show a confirm dialog. You can call it from anywhere, even outside of React. It returns a Promise<boolean> that resolves to true when the user confirms and false when they cancel or dismiss the dialog. This makes it easy to gate destructive actions, navigation, or any flow that needs explicit user consent behind a single await.
Basic usage
The simplest way to use confirm() is to pass a string. The string becomes the dialog title, and the dialog renders with default "Confirm" and "Cancel" buttons.
For full control over the dialog's appearance and behavior, pass an options object instead. This lets you customize the title, description, button labels, variant, and more.
Variant shortcuts
Each variant has a shorthand method that automatically applies the corresponding color scheme and icon styling. Use confirm.danger() for destructive or irreversible actions, confirm.warning() for actions that need caution, confirm.info() for neutral informational prompts, and confirm.success() for positive or completing actions. The shorthand methods accept the same options object as confirm().
Alert mode
Use confirm.alert() when you need to inform the user about something that does not require a decision. The dialog renders with a single "OK" button and no cancel option, so the returned promise always resolves to true. This is ideal for session expirations, completed operations, scheduled maintenance notices, or any message the user simply needs to acknowledge before continuing.
Async loading
Pass an onConfirm handler that returns a Promise to run an asynchronous action when the user confirms. While the promise is pending, the confirm button is automatically disabled and displays a loading spinner. The cancel button is also disabled, and the dialog stays open until the promise resolves. If the promise rejects (throws an error), the dialog stays open and the loading state is reset — the error does not close the dialog. You can also return false from onConfirm to explicitly keep the dialog open. This prevents double-submissions and gives the user clear visual feedback that their action is being processed.
Cancel while loading
By default, the cancel button is disabled during loading. Set cancelableWhileLoading to true to let users cancel even while an async action is in progress.
Type-to-confirm
For high-risk destructive actions where you want an extra layer of safety, use the confirmationKeyword option. The confirm button stays disabled until the user types the exact keyword into an input field. This pattern is familiar from services like GitHub, which require you to type the repository name before allowing deletion. It ensures the action is fully intentional and not the result of an accidental click.
Centered layout
Set layout: 'centered' to position the dialog content in the center of the viewport with centered text alignment. This works well for short, focused prompts where the message is brief and the dialog benefits from a more symmetrical appearance. The default side-aligned layout is better suited for dialogs with longer descriptions or additional form elements.
Hiding icons
By default, variant dialogs (danger, warning, info, success) show an icon. Set icon to false or null to hide it.
Custom actions
Add extra buttons between cancel and confirm using the actions array. Each action has a label and an onClick handler. The dialog closes after the action runs.
Rich descriptions
The description prop accepts any React element, not just strings. Use it to render formatted content, lists, or links.
Custom dialog
Use confirm.custom() to render a completely custom dialog body. You receive a close function that accepts true (confirm) or false (cancel). The overlay, portal, focus trap, and animations are handled by okayy — you control only what goes inside the dialog.
Inline styles
Pass a style object for quick one-off visual tweaks without writing CSS. The styles apply to the dialog container element.
Per-element class names
Use classNames to target individual dialog elements with CSS classes. This is especially useful with Tailwind CSS where you need per-element class control.
Dialog size
Use the size option to control the dialog width. Available presets: "sm" (22rem), "md" (28rem, default), "lg" (36rem), "xl" (48rem), "full" (full viewport width minus padding).
Cancel events
The onCancel callback receives a reason parameter indicating how the dialog was cancelled: "button", "escape", "overlay", or "dismiss". This lets you handle different cancel sources differently, for example logging analytics or performing cleanup only on explicit user cancellation.
const ok = await confirm({
title: 'Delete?',
onCancel: (reason) => {
console.log('Cancelled via:', reason);
// reason is 'button' | 'escape' | 'overlay' | 'dismiss'
},
});okayy also dispatches CustomEvents on window when dialogs close:
window.addEventListener('okayy:confirm', () => console.log('confirmed'));
window.addEventListener('okayy:cancel', () => console.log('cancelled'));
window.addEventListener('okayy:close', (e) => console.log('closed', e.detail.confirmed));Dialog queue
When confirm() is called while a dialog is already open, the new dialog is queued and shown after the current one closes. Each call returns its own Promise<boolean> that resolves when that specific dialog is handled.
// These dialogs show one after another
const a = await confirm('Step 1');
const b = await confirm('Step 2');
const c = await confirm('Step 3');Use confirm.clearQueue() to discard all pending dialogs. Each pending promise resolves with false.
Programmatic dismiss
Close any open confirm dialog from code. This triggers the onCancel callback with reason "dismiss" and calls onDismiss. This is useful when you need to dismiss the dialog in response to external events, such as a route change, a WebSocket message, an inactivity timeout, or any situation where the dialog is no longer relevant and should be removed without waiting for user interaction.
confirm.dismiss();Check open state
Use confirm.isOpen() to check whether a dialog is currently open. Returns true if a dialog is visible, false otherwise.
if (confirm.isOpen()) {
// a dialog is currently open
}API Reference
| Property | Description | Default |
|---|---|---|
| title | Dialog title — the primary question or statement | - |
| description | Supporting content below the title — can be a string or React element | - |
| confirmText | Text for the confirm button | "Confirm" |
| cancelText | Text for the cancel button | "Cancel" |
| variant | Visual variant: "default", "danger", "warning", "info", "success" | "default" |
| icon | Custom icon rendered left of the title. Set to false to hide. | - |
| actions | Additional action buttons between cancel and confirm | - |
| onConfirm | Async action on confirm — shows loading spinner. Return false to keep dialog open. Errors keep dialog open. | - |
| onCancel | Called when the user cancels. Receives reason: "button", "escape", "overlay", "dismiss" | - |
| onDismiss | Called when the dialog closes by any means (confirm, cancel, Escape, overlay) | - |
| dismissible | Whether Escape/overlay click dismisses | true |
| cancelableWhileLoading | Whether the cancel button stays enabled during async loading | false |
| ariaLabel | Custom accessible label for the dialog. Overrides auto-generated labelledby. Useful for i18n. | - |
| className | CSS class on the dialog content container | - |
| overlayClassName | CSS class on the overlay | - |
| hideCancel | Hide the cancel button (used by confirm.alert()) | false |
| confirmationKeyword | Keyword the user must type to enable confirm | - |
| layout | Dialog layout: "default" or "centered" | "default" |
| size | Dialog width preset: "sm", "md", "lg", "xl", "full" | "md" |
| dir | Text direction override: "ltr", "rtl", "auto" | - |
| spinner | Custom spinner element. Set to false to hide spinner (buttons still disabled). | - |
| style | Inline CSS styles on the dialog container | - |
| classNames | Per-element CSS classes (dialog, overlay, title, description, confirmButton, cancelButton, actionButton, icon, content, footer) | - |
| unstyled | Strip all default styles for full Tailwind control | false |
| custom | Render custom dialog body via confirm.custom(). Receives close(boolean). | - |
| testId | Test ID prefix. Sets data-testid on dialog, {testId}-confirm on confirm button, {testId}-cancel on cancel button. | - |