Dialog
A task over the page that has to be finished or dismissed before going on: editing an event, confirming a deletion. It is modal: the page behind can't be used, and focus stays inside. For a short task beside a button that leaves the page usable, use a Popover. Specification: docs/components/dialog.md
A native <dialog> opened by a button with command="show-modal": the browser keeps focus inside, closes it on Escape and gives focus back to the button. It works without JavaScript; canon.js fills in where a browser lacks a part of it.
Basics
A <dialog class="canon-dialog"> with an id, named by its title (aria-labelledby): a .canon-dialog-header (the title, a close button with command="close"), a .canon-dialog-body and a .canon-dialog-footer. A <form method="dialog"> around them makes Save close it with the form's values. The body scrolls when the dialog is taller than the window; .canon-dialog-sections in it run edge to edge with a line between.
Alert dialog
For a decision that interrupts: role="alertdialog", its question in the title and its consequence in the body, which the dialog points at with aria-describedby. No close button: the footer's buttons are the answers. A destructive answer says what it does ("Delete event") with data-intent="danger". Narrow: data-width="sm".
Closing
Escape and the close button close a dialog; focus goes back to the button that opened it. closedby="any" also closes it with a click beside it, for a dialog with nothing to lose (never an alert dialog); closedby="none" keeps it open on Escape, for a task that must be answered with its buttons. The dialog's returnValue is the value of the button that closed it.
Width
data-width: sm for a question, the default for a form, lg for more room. At most the window, less 1rem each side.
Edge cases
Content taller than the window: the body scrolls, the header and footer stay. A long title wraps beside the close button. Right to left, the close button is on the left and the footer runs from the right.