/* SkuaDialog — native <dialog> + showModal().
Markup (from Skua.Components.Overlay.dialog/1):
<dialog id="confirm" phx-hook="SkuaDialog"
phx-mounted={JS.ignore_attributes("open")} data-on-close={…}>
…<button data-sk-close>Cancel</button>…
</dialog>
showModal() gives us the inert backdrop, focus trap, and Esc-to-close for
free. We listen for skua:open / skua:close events (dispatched by
open_dialog/close_dialog), wire any [data-sk-close] buttons, and run the
optional on_close JS command. JS.ignore_attributes("open") (applied in the
component) keeps the dialog open across LiveView re-renders.
*/
export default {
mounted() {
this.open = () => {
if (!this.el.open) this.el.showModal();
};
this.close = () => {
if (this.el.open) this.el.close();
};
this.onOpen = () => this.open();
this.onCloseEvt = () => this.close();
this.el.addEventListener("skua:open", this.onOpen);
this.el.addEventListener("skua:close", this.onCloseEvt);
// [data-sk-close] anywhere inside closes the dialog (the × and Cancel).
this.onClick = (e) => {
if (e.target.closest("[data-sk-close]")) this.close();
};
this.el.addEventListener("click", this.onClick);
// Native close (Esc / requestClose) → run the author's on_close JS.
this.onNativeClose = () => {
const cmd = this.el.dataset.onClose;
if (cmd && cmd !== "[]") this.liveSocket.execJS(this.el, cmd);
};
this.el.addEventListener("close", this.onNativeClose);
},
destroyed() {
this.el.removeEventListener("skua:open", this.onOpen);
this.el.removeEventListener("skua:close", this.onCloseEvt);
this.el.removeEventListener("click", this.onClick);
this.el.removeEventListener("close", this.onNativeClose);
},
};