phx-react
Version:
PHX REACT
48 lines • 2.29 kB
JavaScript
import * as React from 'react';
import { useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
function PortalImpl({ children, closeOnClickOutside, onClose, title, }) {
const modalRef = useRef(null);
useEffect(() => {
if (modalRef.current !== null) {
modalRef.current.focus();
}
}, []);
useEffect(() => {
let modalOverlayElement = null;
const handler = (event) => {
if (event.key === 'Escape') {
onClose();
}
};
const clickOutsideHandler = (event) => {
const target = event.target;
if (modalRef.current !== null && !modalRef.current.contains(target) && closeOnClickOutside) {
onClose();
}
};
const modelElement = modalRef.current;
if (modelElement !== null) {
modalOverlayElement = modelElement.parentElement;
if (modalOverlayElement !== null) {
modalOverlayElement.addEventListener('click', clickOutsideHandler);
}
}
window.addEventListener('keydown', handler);
return () => {
window.removeEventListener('keydown', handler);
if (modalOverlayElement !== null) {
modalOverlayElement === null || modalOverlayElement === void 0 ? void 0 : modalOverlayElement.removeEventListener('click', clickOutsideHandler);
}
};
}, [closeOnClickOutside, onClose]);
return (React.createElement("div", { className: 'Modal__overlay', role: 'dialog' },
React.createElement("div", { ref: modalRef, className: 'Modal__modal', tabIndex: -1 },
React.createElement("h2", { className: 'Modal__title' }, title),
React.createElement("button", { "aria-label": 'Close modal', className: 'Modal__closeButton', onClick: onClose, type: 'button' }, "X"),
React.createElement("div", { className: 'Modal__content' }, children))));
}
export default function Modal({ children, closeOnClickOutside = false, onClose, title, }) {
return createPortal(React.createElement(PortalImpl, { closeOnClickOutside: closeOnClickOutside, onClose: onClose, title: title }, children), document.body);
}
//# sourceMappingURL=Modal.js.map