import { Controller } from "@hotwired/stimulus"; export default class extends Controller { static targets = ["modal", "backdrop"]; // TODO: Stimulus >1 connect() { this.showEvent = this.show.bind(this); this.hideEvent = this.hide.bind(this); window.addEventListener("modal:show", this.showEvent); window.addEventListener("modal:hide", this.hideEvent); } // TODO: Stimulus >1 disconnect() { window.removeEventListener("modal:show", this.showEvent); window.removeEventListener("modal:hide", this.hideEvent); } /* * Abrir otro modal, enviando el ID a toda la ventana. */ showAnother(event = undefined) { event?.preventDefault(); if (!event.target?.dataset?.modalShowValue) return; window.dispatchEvent(new CustomEvent("modal:show", { detail: { id: event.target.dataset.modalShowValue, previousFocus: event.target.id } })); } /* * Podemos enviar la orden de apertura como un click o como un * CustomEvent incluyendo el id del modal como detail. * * El elemento clicleable puede tener un valor que se refiera a otro * modal tambiƩn. */ show(event = undefined) { event?.preventDefault(); const modalId = event?.detail?.id; if (modalId && this.element.id !== modalId) return; this.modalTarget.style.display = "block"; this.backdropTarget.style.display = "block"; this.modalTarget.setAttribute("role", "dialog"); this.modalTarget.setAttribute("aria-modal", true); this.modalTarget.removeAttribute("aria-hidden"); window.document.body.classList.add("modal-open"); if (event?.detail?.previousFocus) { this.previousFocus = window.document.getElementById(event.detail.previousFocus); } else { this.previousFocus = event?.target; } setTimeout(() => { this.modalTarget.classList.add("show"); this.backdropTarget.classList.add("show"); this.modalTarget.focus(); }, 1); } hideWithEscape(event) { if (event?.key !== "Escape") return; this.hide(); } hide(event = undefined) { event?.preventDefault(); const modalId = event?.detail?.id; if (modalId && this.element.id !== modalId) return; this.backdropTarget.classList.remove("show"); this.modalTarget.classList.remove("show"); this.modalTarget.setAttribute("aria-hidden", true); this.modalTarget.removeAttribute("role"); this.modalTarget.removeAttribute("aria-modal"); this.previousFocus?.focus(); setTimeout(() => { this.modalTarget.style.display = ""; this.backdropTarget.style.display = ""; }, 500); window.document.body.classList.remove("modal-open"); } }