5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-11-22 15:36:22 +00:00
panel/app/javascript/controllers/modal_controller.js
2024-07-20 15:21:03 -03:00

95 lines
2.6 KiB
JavaScript

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");
}
}