demo · v131
cancel a close with a dirty-form guard
A modal dialog close request fires a cancellable cancel event first. If that event is not prevented, the dialog closes and reports the transition with beforetoggle, toggle, and close. Paired with a dirty-form tracker this gives you the canonical "are you sure you want to discard?" confirmation without a mutation observer.
how the guard works
The cancel button calls requestClose(), the same close-request pipeline used by the Esc key. The log records cancel first, then the non-cancellable close transition through beforetoggle, toggle, and close. Dirty forms call preventDefault() during cancel and keep the editor open until the user confirms discard.
the api
let dirty = false;
form.addEventListener("input", () => { dirty = true; });
cancelButton.addEventListener("click", () => dialog.requestClose("cancel"));
dialog.addEventListener("cancel", (e) => {
if (dirty) {
e.preventDefault(); // block this close request
confirmDialog.showModal();
}
});
dialog.addEventListener("beforetoggle", (e) => {
console.log(e.oldState, e.newState, e.cancelable);
});