OPERATOR

ConfirmDialog

Basic

Pass title, trigger, onConfirm, and an optional description. Confirm starts enabled.

Destructive

Use confirmVariant="danger" for irreversible actions.

Typed confirmation

Set confirmPhrase to require an exact match before enabling Confirm. The field is named by its visible label, Type "WIPE" to confirm.

Long content

ConfirmDialog is built on Dialog: a long description scrolls between the pinned title and the Cancel and Confirm buttons, and the dialog fits the visible screen less a margin. Long titles, phrases and button labels wrap. trigger takes one focusable element that forwards its ref, such as a Button; plain text renders as a Button. The forwarded ref receives the dialog's <section>, typed HTMLElement.

Props

PROPTYPEDEFAULTREQUIRED
titlestring—yes
descriptionstring—no
confirmLabelstring"CONFIRM"no
cancelLabelstring"CANCEL"no
confirmVariantenum
primary | danger
"primary"no
confirmPhrasestring—no
onConfirmfunction—yes
sizeenum
sm | md | lg
"md"no
openboolean—no
defaultOpenboolean—no
onOpenChangefunction—no

Accessibility

  • Focus stays inside the dialog and returns to the trigger on close.
  • Escape and the overlay dismiss through onOpenChange.
  • Give destructive actions explicit labels alongside the danger color.
  • Typed confirmation uses an input named by its visible label. Confirm remains visibly disabled until the phrase matches; the flow works by keyboard.

Manifest entry

<ConfirmDialog
  title="DELETE UNIT"
  description="This permanently removes UNIT-07 from the roster."
  confirmPhrase="UNIT-07"
  confirmVariant="danger"
  confirmLabel="DELETE"
  trigger={<Button variant="danger">DELETE</Button>}
  onConfirm={() => deleteUnit("UNIT-07")}
/>
View agent manifest
{
  "description": "Confirmation modal for destructive or high-consequence actions. Composes Dialog + Button (+ Field + Input for typed confirmation). Flat API: pass title, optional description, onConfirm, and an optional confirmPhrase the user must type exactly to enable Confirm.",
  "props": {
    "title": {
      "type": "string",
      "required": true
    },
    "description": {
      "type": "string"
    },
    "confirmLabel": {
      "type": "string",
      "default": "CONFIRM"
    },
    "cancelLabel": {
      "type": "string",
      "default": "CANCEL"
    },
    "confirmVariant": {
      "type": "enum",
      "values": [
        "primary",
        "danger"
      ],
      "default": "primary"
    },
    "confirmPhrase": {
      "type": "string"
    },
    "onConfirm": {
      "type": "function",
      "required": true
    },
    "size": {
      "type": "enum",
      "values": [
        "sm",
        "md",
        "lg"
      ],
      "default": "md"
    },
    "open": {
      "type": "boolean"
    },
    "defaultOpen": {
      "type": "boolean"
    },
    "onOpenChange": {
      "type": "function"
    }
  },
  "slots": {
    "trigger": {
      "type": "focusable element | text (text renders a Button)"
    }
  },
  "composable_with": [
    "Card",
    "Toolbar"
  ],
  "never_inside": [
    "Dialog",
    "ConfirmDialog"
  ],
  "example": "<ConfirmDialog\n  title=\"DELETE UNIT\"\n  description=\"This permanently removes UNIT-07 from the roster.\"\n  confirmPhrase=\"UNIT-07\"\n  confirmVariant=\"danger\"\n  confirmLabel=\"DELETE\"\n  trigger={<Button variant=\"danger\">DELETE</Button>}\n  onConfirm={() => deleteUnit(\"UNIT-07\")}\n/>"
}

On this page