Holo Dialog
The <holo-dialog> component wraps the native <dialog> element, using showModal()/close() for
focus trapping, the top layer, and ::backdrop styling — no hand-rolled JS focus trap needed. When
dismissible (the default), Esc, a backdrop click, or the close button dismiss the dialog. Closing
returns focus to whatever element triggered it.
When to use
Section titled “When to use”Use it for:
- A task or message that needs the user’s full attention before they continue: confirm a deletion, edit a record.
- Short, focused interactions with a clear way out.
Don’t use it for:
- Non-blocking feedback. Use Toast or Alert.
- Secondary panels that slide in from an edge. Use Drawer.
- Lightweight floating content anchored to a trigger. Use Popover.
- Long forms or whole pages. Give them their own page.
Live Previews
Section titled “Live Previews”Basic dialog
Section titled “Basic dialog”Are you sure you want to continue?
<button id="trigger">Open dialog</button><holo-dialog id="dialog" heading="Confirm action"> <p>Are you sure you want to continue?</p> <button slot="footer">Confirm</button></holo-dialog>
<script> trigger.addEventListener('click', () => dialog.setAttribute('open', '')); dialog.addEventListener('holoClose', () => dialog.removeAttribute('open'));</script>Accessibility
Section titled “Accessibility”The component renders a native <dialog> and opens it with showModal(). The browser makes the rest of the page inert, traps focus in the dialog and puts it in the top layer. It is named by its heading (an <h2> referenced with aria-labelledby), or by aria-label="Dialog" when no heading is set. The default slot is the body and the footer slot is the footer.
| Key | Action |
|---|---|
Tab |
Moves to the next focusable element inside the dialog, wrapping at the end |
Shift + Tab |
Moves to the previous focusable element, wrapping at the start |
Esc |
Closes the dialog when dismissible |
Enter, Space |
Activates the focused button (such as the close button) |
- When the dialog opens, the focused element is saved, following open shadow roots down to the element that really has focus (for example the inner
<button>of a Button). Focus returns to it when the dialog closes. - With
dismissible(the default) a close button named “Close dialog” is shown, andEscand a backdrop click close the dialog. - With
dismissibleset tofalsethere is no close button, andEscand backdrop clicks are ignored. Close the dialog from your own content by settingopentofalse. Browsers may still close a modal dialog ifEscis pressed repeatedly without other interaction, so keepopenin sync withholoClose. - Initial focus follows the browser default for
showModal(): the first focusable element. - The fade only runs when
prefers-reduced-motion: no-preference.
You provide:
- A
heading. Without it the dialog is named only “Dialog”. - At least one focusable control inside the dialog, and a clear way to finish or cancel. With
dismissibleset tofalse, that control is the only way out. - A trigger that is still in the page when the dialog closes, so focus can return to it.
API Reference
Section titled “API Reference”Importing
import '@philbob-sideprojects/hololink-ui/holo-dialog';Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
dismissible | dismissible | boolean | true | If true, renders a close button in the header and lets Esc and backdrop clicks close the
dialog. If false, close it from your own content by setting open to false. |
heading | heading | string | — | Optional heading rendered in the dialog header. |
open | open | boolean | false | Whether the dialog is open. Setting this to true calls the native
showModal(); setting it to false calls close(). |
Events
| Event | Detail | Description |
|---|---|---|
holoClose | void | Emitted after the dialog has closed (via Esc, backdrop click, the close button, or open being
set to false; Esc and backdrop click only when dismissible). Focus then returns to the
element that was focused when the dialog opened. |
holoOpen | void | Emitted after the dialog opens in response to open becoming true. |
Slots
| Slot | Description |
|---|---|
| (default) | The dialog body content. |
footer | Action buttons rendered in the dialog footer. |
CSS custom properties
| Property | Description |
|---|---|
--holo-dialog-backdrop-bg | Background of the backdrop behind the dialog. |
--holo-dialog-bg | Background color of the dialog. |
--holo-dialog-max-width | Maximum width of the dialog. |
--holo-dialog-radius | Corner radius of the dialog. |
--holo-dialog-shadow | Box shadow of the dialog. |
--holo-dialog-text-color | Text color of the dialog. |