| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- import React, { FC, useState, useEffect, MouseEventHandler } from "react";
- import { createPortal } from "react-dom";
- import { Modal as BsModal } from "bootstrap";
- // Este componente es un react portal. No se va a montar adentro de el componente donde lo uses.
- // Cuando lo uses, va a montarse siempre en el mismo lugar, pero tenes acceso a todos sus eventos de todas formas.
- const Modal: FC<ModalProps> = ({
- children,
- accept,
- dismiss,
- acceptText = "Aceptar",
- dismissText = "Cancelar",
- title,
- buttons = true,
- staticBackdrop = false,
- }) => {
- // Mounting point
- const root = document.getElementById("modal-portal");
- const [bsModal, setBsModal] = useState<BsModal | null>(null);
- useEffect(() => {
- const modalEl = document.getElementById("page-modal");
- let modalTemp: null | BsModal = null;
- if (!modalEl) return;
- console.log("Effect run", { staticBackdrop });
- if (staticBackdrop) {
- console.log({ modalEl });
- modalEl.setAttribute("data-bs-backdrop", "static");
- }
- if (!bsModal) {
- modalTemp = new BsModal(modalEl);
- setBsModal(modalTemp);
- }
- modalTemp?.show();
- return () => {
- modalTemp?.hide();
- modalEl?.removeAttribute("data-bs-backdrop");
- };
- }, []);
- const content = (
- <div className="modal-content">
- {title ? (
- <div className="modal-header">
- <h5 className="modal-title">{title}</h5>
- <button
- type="button"
- className="btn-close"
- data-bs-dismiss="modal"
- aria-label="Close"
- ></button>
- </div>
- ) : null}
- <div className="modal-body">{children}</div>
- {buttons && (dismiss || accept) && (
- <div className="modal-footer">
- {dismiss && (
- <button
- type="button"
- className="btn btn-secondary"
- data-bs-dismiss="modal"
- onClick={dismiss}
- >
- {dismissText}
- </button>
- )}
- {accept && (
- <button type="button" onClick={accept} className="btn btn-primary">
- {acceptText}
- </button>
- )}
- </div>
- )}
- </div>
- );
- if (!root) return null;
- return createPortal(content, root);
- };
- interface ModalProps {
- title?: string;
- buttons?: boolean;
- dismiss?: MouseEventHandler<HTMLButtonElement>;
- accept?: MouseEventHandler<HTMLButtonElement>;
- dismissText?: string;
- acceptText?: string;
- staticBackdrop?: boolean;
- }
- export default Modal;
|