Overlay
ConfirmDialog
Confirmation modal built on Dialog. Uses role="alertdialog", lands focus on the cancel button and treats Escape as cancel; the backdrop never dismisses it.
Import
import { ConfirmDialog } from "@zephora/react";Examples
Destructive confirmation
`destructive` renders the confirm button in the danger variant.
const [open, setOpen] = React.useState(false);
<Button variant="danger" onClick={() => setOpen(true)}>Delete project</Button>
<ConfirmDialog
open={open}
onOpenChange={setOpen}
title="Delete this project?"
description="All deployments and data will be removed. This cannot be undone."
confirmLabel="Delete"
destructive
onConfirm={() => setOpen(false)}
/>Async confirm
Keep the dialog open while the action runs — `loading` shows a spinner on the confirm button.
const [open, setOpen] = React.useState(false);
const [loading, setLoading] = React.useState(false);
<ConfirmDialog
open={open}
onOpenChange={setOpen}
title="Publish changes?"
description="The new version goes live immediately."
confirmLabel="Publish"
loading={loading}
onConfirm={() => {
setLoading(true);
setTimeout(() => {
setLoading(false);
setOpen(false);
}, 1200);
}}
/>API
ConfirmDialog props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | Controlled open state. |
onOpenChange | (open: boolean) => void | — | Called whenever the dialog requests an open state change. |
title * | ReactNode | — | Heading of the confirmation. |
description | ReactNode | — | Supporting text explaining the consequence. |
confirmLabel | ReactNode | "Confirm" | Label of the confirm button. |
cancelLabel | ReactNode | "Cancel" | Label of the cancel button. |
destructive | boolean | false | Renders the confirm button in the danger variant. |
loading | boolean | false | Shows a spinner on the confirm button while the action runs. |
onConfirm * | () => void | — | Called when the user confirms. Closing afterwards is up to the caller. |
onCancel | () => void | — | Called when the user cancels (cancel button or Escape). |
unstyled | boolean | false | Headless mode — skips Zephora styling. |
Keyboard
| Key | Action |
|---|---|
Escape | Cancels — fires onCancel and requests close. |
Tab / Shift+Tab | Cycles between the cancel and confirm buttons; focus starts on cancel. |