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.