From b78baf4cfbe9ecc914ef01f86686d689ed557946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E4=BB=81?= Date: Mon, 3 Aug 2026 10:28:36 +0800 Subject: [PATCH 1/6] feat: declarative custom element adds a customized built-in element so a lightbox can be written in html, while keeping every existing feature and api untouched. - split src/js/dialogify.js into core.js (class) + element.js (element) and a thin dialogify.js entry that registers the element - the element name is prefixed because custom element names must contain a hyphen, so is="dialogify" is not valid - dialogify methods (show/showModal/isOpen/setTitle/buttons/on) live on the element returned by document.querySelector() - options via attributes: dialog-title, size, closable, fixed, background-scroll, use-dialog-form, src, ajax-prefix, buttons-position and options='{...}' for anything else - declarative buttons via + + +``` + +```javascript +const dialog = document.querySelector('dialog[is="bahamut-dialogify"]'); +dialog.showModal(); +``` + +The element name is prefixed because the custom elements spec requires a hyphen +in the name — `is="dialogify"` is not a valid custom element name. + +Unlike `new Dialogify()`, a declarative dialog is **not** removed from the DOM when +it closes, so it can be shown again. + +### Methods + +`document.querySelector(...)` returns the element itself, and the dialogify API is +available on it: + +| Method | Description | +| ---------------------------- | -------------------------------- | +| `show()` | Show the dialog (non-modal) | +| `showModal()` | Show the dialog as a modal | +| `close(returnValue?)` | Native `` close | +| `isOpen()` | Whether the dialog is open | +| `setTitle(text)` | Set the dialog title | +| `buttons(buttons, options?)` | Add buttons programmatically | +| `on(event, handler)` | Bind a dialogify instance event | +| `.dialogify` | The backing `Dialogify` instance | + +> `setTitle()` is used instead of `title()` because `HTMLElement.title` is the +> native tooltip property and must keep its standard behaviour. + +### Options as attributes + +| Attribute | Option | Notes | +| ------------------- | ------------------ | ------------------------------------------------------------- | +| `dialog-title` | — | Dialog title (`title` is the native tooltip) | +| `size="large"` | `size` | Maps to `Dialogify.SIZE_LARGE`; any other value is used as-is | +| `closable` | `closable` | Show the close button | +| `fixed` | `fixed` | Use `position: fixed` | +| `background-scroll` | `backgroundScroll` | Allow scrolling behind the dialog | +| `use-dialog-form` | `useDialogForm` | Wrap content in `
` | +| `src` | — | Load content from this URL instead of the inline markup | +| `ajax-prefix` | `ajaxPrefix` | Ajax prefix used to resolve `src` | +| `options='{...}'` | — | Any option as a JSON object | +| `buttons-position` | — | `left` / `center` / `right` (default `right`) | + +> ⚠️ Because attributes are strings, these booleans are **value-based**, not +> presence-based: use `closable="false"` to disable. A bare attribute, `"true"`, +> or any other value means `true`. This differs from standard HTML boolean +> attributes. + +Options that cannot be expressed as attributes (callbacks, style objects) can be +assigned before the dialog is first shown: + +```javascript +dialog.options = { + ajaxComplete() { + /* ... */ + } +}; +``` + +### Buttons + +Add a ` + +
+``` + +> Write ``, not `