Appearance
QsDialog
<qs-dialog>alphaA modal dialog built on the native <dialog> element: focus is trapped and
restored, Esc closes it, and the rest of the page becomes inert.
Three zones: a title bar (with a close button), the content (any children),
and an optional action bar that only shows when children carry
slot="actions". Wrap actions in <form method="dialog"> to close the dialog
with no script.
Anatomy
A closed dialog, laid out flat on the page so you can see the three zones. The page CSS only overrides the modal positioning.
Content: any child without a slot. Long content scrolls here.
No slot="actions" child, so no action bar.
Examples
The file moves out of the shared folder for everyone. This can’t be undone.
Themes are here. Switch between Editorial and Industrial from the top bar; every component follows.
Long content scrolls inside the dialog while the title and action bars stay in place.
Lorem-free filler: the quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. How vexingly quick daft zebras jump. Sphinx of black quartz, judge my vow.
The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. How vexingly quick daft zebras jump. Sphinx of black quartz, judge my vow.
The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. How vexingly quick daft zebras jump. Sphinx of black quartz, judge my vow.
The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. How vexingly quick daft zebras jump. Sphinx of black quartz, judge my vow.
The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. How vexingly quick daft zebras jump. Sphinx of black quartz, judge my vow.
html
<qs-button variant="primary" onclick="document.getElementById('confirm').show()">Delete file…</qs-button>
<qs-dialog id="confirm" label="Delete “Q3 report.pdf”?">
<p>The file moves out of the shared folder for everyone. This can’t be undone.</p>
<form method="dialog" slot="actions">
<qs-button>Cancel</qs-button>
<qs-button variant="danger" icon="trash">Delete</qs-button>
</form>
</qs-dialog>Prop
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | false | Whether the dialog is shown. Set it, or call `show()` / `close()`. |
label | string | "" | Title shown in the title bar; also the dialog's accessible name. Required. |
text | string | — | The text content of the element, captured from light DOM before the first render. |
Usage
The dialog has three zones:
- Title bar. It shows
labeland a close button. The title is also the dialog's accessible name. - Content. Every child without a
slotgoes here, styled by you or byqs-text. Long content scrolls inside this zone while the title and action bars stay put. - Action bar. Children with
slot="actions"go here. With no such child, the bar is not rendered at all.
Opening and closing
- Open: call
show(), or set theopenattribute. - Close: the close button, Esc,
close(returnValue), or any submit button inside a<form method="dialog">. Every route fires acloseevent on<qs-dialog>and resetsopen.
js
const dialog = document.getElementById("confirm");
dialog.addEventListener("close", () => console.log("closed"));
dialog.show();Put the actions in <form method="dialog"> so they close the dialog without any script. Use close() when an action has to do async work first.
Do and don't
- Keep it to one primary or danger action, placed last.
- Use a dialog for decisions that block the flow. Don't use it for information the user could read inline.
- Don't stack dialogs.
Accessibility
- It is built on native
<dialog>+showModal(). Focus moves inside and is trapped there, the page behind becomes inert, Esc closes it, and focus returns to the trigger. labelis both the visible title and the dialog's accessible name (aria-label). Always set it: without it the dialog logs a console warning.- The close button is icon-only with the accessible name "Close" (through
qs-button'slabelprop). - Motion: it scales in from 0.97 and fades over 200ms, and leaves faster (120ms). With reduced motion it only fades. In the Industrial theme it steps in and closes instantly.
Responsive
The dialog is at most --qs-dialog-width wide (560px) and keeps a --qs-dialog-viewport-gap margin to the screen edges. Its height is capped to the visible screen (100dvh), and the action buttons wrap on narrow screens.