2024-07-20 18:21:03 +00:00
|
|
|
import { Controller } from "@hotwired/stimulus";
|
2024-05-17 18:06:44 +00:00
|
|
|
|
|
|
|
export default class extends Controller {
|
|
|
|
static targets = ["modal", "backdrop"];
|
|
|
|
|
2024-05-18 21:03:01 +00:00
|
|
|
// TODO: Stimulus >1
|
|
|
|
connect() {
|
|
|
|
this.showEvent = this.show.bind(this);
|
2024-05-18 21:48:49 +00:00
|
|
|
this.hideEvent = this.hide.bind(this);
|
2024-05-18 21:03:01 +00:00
|
|
|
|
|
|
|
window.addEventListener("modal:show", this.showEvent);
|
2024-05-18 21:48:49 +00:00
|
|
|
window.addEventListener("modal:hide", this.hideEvent);
|
2024-05-18 21:03:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Stimulus >1
|
|
|
|
disconnect() {
|
|
|
|
window.removeEventListener("modal:show", this.showEvent);
|
2024-05-18 21:48:49 +00:00
|
|
|
window.removeEventListener("modal:hide", this.hideEvent);
|
2024-05-18 21:03:01 +00:00
|
|
|
}
|
|
|
|
|
2024-06-03 20:52:53 +00:00
|
|
|
/*
|
|
|
|
* Abrir otro modal, enviando el ID a toda la ventana.
|
|
|
|
*/
|
|
|
|
showAnother(event = undefined) {
|
|
|
|
event?.preventDefault();
|
|
|
|
|
|
|
|
if (!event.target?.dataset?.modalShowValue) return;
|
|
|
|
|
2024-06-05 21:01:44 +00:00
|
|
|
window.dispatchEvent(new CustomEvent("modal:show", { detail: { id: event.target.dataset.modalShowValue, previousFocus: event.target.id } }));
|
2024-06-03 20:52:53 +00:00
|
|
|
}
|
|
|
|
|
2024-05-18 21:03:01 +00:00
|
|
|
/*
|
|
|
|
* Podemos enviar la orden de apertura como un click o como un
|
|
|
|
* CustomEvent incluyendo el id del modal como detail.
|
2024-06-03 20:52:53 +00:00
|
|
|
*
|
|
|
|
* El elemento clicleable puede tener un valor que se refiera a otro
|
|
|
|
* modal también.
|
2024-05-18 21:03:01 +00:00
|
|
|
*/
|
2024-05-17 18:06:44 +00:00
|
|
|
show(event = undefined) {
|
|
|
|
event?.preventDefault();
|
2024-05-18 21:03:01 +00:00
|
|
|
const modalId = event?.detail?.id;
|
|
|
|
|
|
|
|
if (modalId && this.element.id !== modalId) return;
|
2024-05-17 18:06:44 +00:00
|
|
|
|
|
|
|
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");
|
|
|
|
|
2024-06-05 21:01:44 +00:00
|
|
|
if (event?.detail?.previousFocus) {
|
|
|
|
this.previousFocus = window.document.getElementById(event.detail.previousFocus);
|
|
|
|
} else {
|
|
|
|
this.previousFocus = event?.target;
|
|
|
|
}
|
|
|
|
|
2024-05-17 18:06:44 +00:00
|
|
|
setTimeout(() => {
|
|
|
|
this.modalTarget.classList.add("show");
|
|
|
|
this.backdropTarget.classList.add("show");
|
2024-06-05 21:01:44 +00:00
|
|
|
|
|
|
|
this.modalTarget.focus();
|
2024-05-17 18:06:44 +00:00
|
|
|
}, 1);
|
|
|
|
}
|
|
|
|
|
2024-06-05 21:00:55 +00:00
|
|
|
hideWithEscape(event) {
|
|
|
|
if (event?.key !== "Escape") return;
|
|
|
|
|
|
|
|
this.hide();
|
|
|
|
}
|
|
|
|
|
2024-05-17 18:06:44 +00:00
|
|
|
hide(event = undefined) {
|
|
|
|
event?.preventDefault();
|
2024-05-18 21:48:49 +00:00
|
|
|
const modalId = event?.detail?.id;
|
|
|
|
|
|
|
|
if (modalId && this.element.id !== modalId) return;
|
2024-05-17 18:06:44 +00:00
|
|
|
|
|
|
|
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");
|
|
|
|
|
2024-06-05 21:01:44 +00:00
|
|
|
this.previousFocus?.focus();
|
|
|
|
|
2024-05-17 18:06:44 +00:00
|
|
|
setTimeout(() => {
|
|
|
|
this.modalTarget.style.display = "";
|
|
|
|
this.backdropTarget.style.display = "";
|
|
|
|
}, 500);
|
|
|
|
|
|
|
|
window.document.body.classList.remove("modal-open");
|
|
|
|
}
|
|
|
|
}
|