phanpy/src/components/modal.jsx

85 wiersze
2.1 KiB
React
Czysty Zwykły widok Historia

2022-12-10 09:14:48 +00:00
import './modal.css';
import { createPortal } from 'preact/compat';
2022-12-30 12:37:57 +00:00
import { useEffect, useRef } from 'preact/hooks';
import { useHotkeys } from 'react-hotkeys-hook';
2022-12-10 09:14:48 +00:00
import useCloseWatcher from '../utils/useCloseWatcher';
2022-12-10 09:14:48 +00:00
const $modalContainer = document.getElementById('modal-container');
function Modal({ children, onClose, onClick, class: className }) {
2022-12-10 09:14:48 +00:00
if (!children) return null;
2022-12-30 12:37:57 +00:00
const modalRef = useRef();
useEffect(() => {
let timer = setTimeout(() => {
const focusElement = modalRef.current?.querySelector('[tabindex="-1"]');
if (focusElement) {
focusElement.focus();
}
}, 100);
return () => clearTimeout(timer);
}, []);
const supportsCloseWatcher = window.CloseWatcher;
const escRef = useHotkeys(
'esc',
2023-10-26 03:16:34 +00:00
() => {
setTimeout(() => {
onClose?.();
}, 0);
},
{
enabled: !supportsCloseWatcher && !!onClose,
2023-10-26 03:16:34 +00:00
// Using keyup and setTimeout above
// This will run "later" to prevent clash with esc handlers from other components
keydown: false,
keyup: true,
},
[onClose],
);
useCloseWatcher(onClose, [onClose]);
2022-12-10 09:14:48 +00:00
const Modal = (
<div
ref={(node) => {
modalRef.current = node;
escRef.current = node?.querySelector?.('[tabindex="-1"]') || node;
}}
className={className}
onClick={(e) => {
onClick?.(e);
if (e.target === e.currentTarget) {
onClose?.(e);
}
}}
tabIndex="-1"
onFocus={(e) => {
2024-02-26 05:59:26 +00:00
try {
if (e.target === e.currentTarget) {
const focusElement =
modalRef.current?.querySelector('[tabindex="-1"]');
const isFocusable =
!!focusElement &&
2024-02-26 05:59:26 +00:00
getComputedStyle(focusElement)?.pointerEvents !== 'none';
if (focusElement && isFocusable) {
focusElement.focus();
}
}
} catch (err) {
console.error(err);
2023-09-14 17:10:58 +00:00
}
}}
>
2022-12-10 09:14:48 +00:00
{children}
</div>
);
return createPortal(Modal, $modalContainer);
// return createPortal(children, $modalContainer);
2022-12-16 05:27:04 +00:00
}
export default Modal;