Created
August 26, 2021 02:20
-
-
Save ErikGMatos/69a2b63ac81b59f443c45d00abb50546 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useEffect, useState, useRef } from 'react'; | |
import { createPortal } from 'react-dom'; | |
import PropTypes from 'prop-types'; | |
import usePortal from '~/components/Portal'; | |
import { | |
ModalCrm, | |
Overlay, | |
ButtonClose, | |
ModalWrap, | |
ModalWrapDad, | |
Header, | |
Title, | |
} from './styles'; | |
export default function Modal({ | |
id, | |
children, | |
handleClose, | |
closeOverlay, | |
hasCloseButton, | |
title, | |
icon: IconHeader, | |
maxHeight, | |
open, | |
successCallback, | |
errorCallback, | |
closeCallbackType, | |
setCloseCallbackType, | |
...rest | |
}) { | |
const containerId = id || 'AppModal'; | |
const target = usePortal(containerId); | |
const [animation, setAnimation] = useState(false); | |
const [isOpenModal, setIsOpenModal] = useState(false); | |
const [shouldRender, setShouldRender] = useState(false); | |
const [close, setClose] = useState(false); | |
const modalRef = useRef(null); | |
useEffect(() => { | |
if (!closeCallbackType) return; | |
setClose(true); | |
setCloseCallbackType(false); | |
setTimeout( | |
() => | |
({ | |
error: errorCallback, | |
success: successCallback, | |
close: handleClose, | |
}[closeCallbackType]()), | |
200 | |
); | |
}, [ | |
setCloseCallbackType, | |
closeCallbackType, | |
errorCallback, | |
successCallback, | |
handleClose, | |
]); | |
useEffect(() => { | |
if (close) { | |
setAnimation(false); | |
setIsOpenModal(false); | |
document.body.style.overflow = ''; | |
return; | |
} | |
document.body.style.overflow = 'hidden'; | |
setTimeout(() => { | |
if (!modalRef.current) return; | |
setShouldRender(true); | |
setIsOpenModal(true); | |
setAnimation(true); | |
}, 50); | |
}, [close]); | |
function closeModal() { | |
setClose(true); | |
setCloseCallbackType(false); | |
setTimeout(() => { | |
handleClose(); | |
}, 200); | |
} | |
return createPortal( | |
<> | |
<ModalWrapDad isOpen={isOpenModal}> | |
<ModalWrap isOpen={isOpenModal}> | |
<Overlay | |
isOpen={isOpenModal} | |
animation={animation} | |
onClick={closeOverlay ? closeModal : null} | |
/> | |
<ModalCrm | |
ref={modalRef} | |
isOpen={isOpenModal} | |
animation={animation} | |
maxHeight={maxHeight} | |
{...rest} | |
> | |
{hasCloseButton && <ButtonClose onClick={closeModal} />} | |
{title || IconHeader ? ( | |
<Header> | |
{IconHeader && ( | |
<IconHeader | |
style={{ width: '64px', margin: '0 auto 16px' }} | |
/> | |
)} | |
{title && <Title>{title}</Title>} | |
</Header> | |
) : null} | |
{shouldRender && children} | |
</ModalCrm> | |
</ModalWrap> | |
</ModalWrapDad> | |
</>, | |
target | |
); | |
} | |
Modal.propTypes = { | |
children: PropTypes.oneOfType([PropTypes.element, PropTypes.array]), | |
handleClose: PropTypes.func, | |
closeOverlay: PropTypes.bool, | |
hasCloseButton: PropTypes.bool, | |
title: PropTypes.string, | |
icon: PropTypes.oneOfType([ | |
PropTypes.func, | |
PropTypes.object, | |
PropTypes.string, | |
]), | |
maxHeight: PropTypes.string, | |
closeCallbackType: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]), | |
setCloseCallbackType: PropTypes.func, | |
}; | |
Modal.defaultProps = { | |
children: null, | |
handleClose: () => null, | |
closeOverlay: true, | |
hasCloseButton: true, | |
title: '', | |
icon: null, | |
maxHeight: '98%', | |
closeCallbackType: false, | |
setCloseCallbackType: () => null, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment