modal / modalTrigger
A <dialog>-based modal with backdrop, animated open/close, and keyboard dismiss. The Pulse runtime handles open and close natively — no extra script needed.
// Render the dialog somewhere on the page
modal({
id: 'confirm-delete',
title: 'Confirm action',
content: '<p>Are you sure? This cannot be undone.</p>',
footer:
button({ label: 'Cancel', variant: 'secondary' }) +
button({ label: 'Delete', variant: 'danger' }),
})
// Open it with a trigger button (or any element with data-dialog-open)
modalTrigger({ target: 'confirm-delete', label: 'Delete item', variant: 'danger' })Sizes
modal({ id: 'my-modal', title: 'Large modal', size: 'lg', content: '...' })| Prop | Type | Default | |
|---|---|---|---|
id | string | — | Unique ID — required for triggers to target this dialog |
title | string | — | |
level | number | 2 | Heading tag for the title (1–6). Visual style is unchanged. |
content | string (HTML) | — | Body HTML |
footer | string (HTML) | — | Footer HTML — typically button() calls |
size | sm | md | lg | xl | md | |
class | string | — |
modalTrigger props
| Prop | Type | Default | |
|---|---|---|---|
target | string | — | The modal's id |
label | string | Open | |
variant | primary | secondary | ghost | danger | primary | |
size | sm | md | lg | md | |
class | string | — |
Custom triggers
Any element with data-dialog-open="<id>" opens the dialog when clicked. Use data-dialog-close on any element inside or outside the dialog to close it programmatically:
<button data-dialog-open="my-modal">Open</button>
<button data-dialog-close>Cancel</button>
The dialog also closes on ESC, backdrop click, and
<form method="dialog"> submit — all native browser behaviour, no JavaScript needed.Forms inside a modal
modal() wraps all content in <form method="dialog"> for native close behaviour. You cannot nest a <form data-action="..."> inside it — browsers silently discard nested forms, so the action will never fire.
When a modal button needs to trigger a Pulse action, place the form outside the modal and use the HTML form attribute to associate the button with it:
// The action form lives outside the modal — hidden, no visible fields needed
<form id="delete-form" data-action="deleteAccount" style="display:none"></form>
${modal({
id: 'confirm-delete',
title: 'Delete account?',
content: '<p>This cannot be undone.</p>',
footer:
// type="submit" with no form= closes the modal natively (submits <form method="dialog">)
button({ label: 'Cancel', variant: 'secondary', type: 'submit' }) +
// form="delete-form" associates this button with the external form → fires the action
button({ label: 'Confirm delete', variant: 'danger', attrs: { form: 'delete-form', type: 'submit' } }),
})}
The hidden form needs no visible fields.
onStart receives state and formData — read anything you need from state directly.