Confirm action dialog

The Alert dialog around a pending mutation. The confirm is a plain Button, not AlertDialogAction (which auto-closes before the mutation settles): it goes busy while pending, Cancel disables, and Escape and the scrim are blocked so the mutation can never complete invisibly. The caller closes once the mutation settles. Destructive takes the one filled red, ends the footer on Cancel and focuses Cancel so Enter cannot destroy.

<ConfirmActionDialog
  open={open} onOpenChange={setOpen}
  title="Delete this lot?" description="…"
  confirmLabel="Delete lot" cancelLabel="Keep lot" pendingLabel="Deleting"
  variant="destructive" isPending={mutation.isPending}
  onConfirm={() => mutation.mutate(id, { onSuccess: () => setOpen(false) })}
/>

Destructive

Filled red confirm first, Cancel last and focused. Press it: 1.5s busy state, then the caller closes.

Default

Primary confirm last; children render between the description and the footer for the thing being acted on.