You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
48 lines
1.4 KiB
JavaScript
48 lines
1.4 KiB
JavaScript
import { useState, useEffect } from 'react';
|
|
import ReactDOM from 'react-dom'
|
|
import {Icon} from '@rmwc/icon'
|
|
import FocusTrap from 'focus-trap-react'
|
|
|
|
import styles from './modal.module.css'
|
|
|
|
export default function Modal({visible, title, children, onDeactivate}){
|
|
const [portalExists, setPortalExists] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const portalExists = !!document.querySelector('#sos-modal');
|
|
|
|
if (!portalExists) {
|
|
const portal = document.createElement('div');
|
|
portal.id = '#sos-modal';
|
|
document.body.appendChild(portal);
|
|
}
|
|
|
|
setPortalExists(true);
|
|
}, []);
|
|
|
|
if(!portalExists)
|
|
return null
|
|
|
|
return ReactDOM.createPortal((
|
|
<div className={styles.modalContainer + (visible?' ' + styles.modalShown:'')}>
|
|
<div className={styles.modalBackground} onClick={onDeactivate}/>
|
|
{visible && (
|
|
<FocusTrap active={visible} focusTrapOptions={{onDeactivate}}>
|
|
<div className={styles.modalScroll}>
|
|
<dialog open className={styles.modal}>
|
|
<div className={styles.titleContainer}>
|
|
<h2>{title}</h2>
|
|
<button className="buttonLink" onClick={onDeactivate}>
|
|
<Icon icon="close"/>
|
|
</button>
|
|
|
|
</div>
|
|
{children}
|
|
</dialog>
|
|
</div>
|
|
</FocusTrap>
|
|
)}
|
|
</div>
|
|
), window.document.body)
|
|
}
|