@hhgtech/hhg-components
Version:
Hello Health Group common components
257 lines (243 loc) • 7.63 kB
JavaScript
;
var React = require('react');
var useScrollbarSize = require('./useScrollbarSize-21ee96fa.js');
var ReactDOM = require('react-dom');
var styled = require('@emotion/styled');
var utils = require('./utils-7ba0038a.js');
var miscDefaultClassWrapper = require('./miscDefaultClassWrapper.js');
var miscTheme = require('./miscTheme.js');
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefault(React);
var styled__default = /*#__PURE__*/_interopDefault(styled);
const StyledModal = miscDefaultClassWrapper.setDefaultClass(styled__default["default"].div `
position: relative;
z-index: 200;
background-color: ${miscTheme.theme.colors.white};
border-radius: ${miscTheme.theme.borderRadius};
box-shadow: 0px 8px 40px 0px #0000001a;
&[data-site-type='marryBaby'] {
border-radius: 16px;
.hhg-modal__content {
position: relative;
z-index: 111;
height: 100%;
padding: 24px;
}
}
.hhg-modal__content {
position: relative;
z-index: 111;
height: 100%;
padding: 16px;
}
.hhg-modal__video {
position: relative;
z-index: 111;
height: 100%;
background-color: none;
box-shadow: none;
}
`, 'hhgcomp-modal-modal');
const StyledModalWrapper = styled__default["default"].div `
position: fixed;
top: 0;
left: 0;
z-index: 201;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
outline: 0;
visibility: hidden;
opacity: 0;
background-color: rgba(0, 0, 0, 0.6);
transition: opacity 0.3s ease-in-out;
.hhg-modal__close {
position: absolute;
top: 16px;
right: 16px;
cursor: pointer;
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
&[data-type='video'] {
z-index: 1001;
}
&[data-open='true'] {
opacity: 1;
visibility: visible;
}
${StyledModal.classSelector} {
transition: transform 0.3s ease-in-out;
}
&.slideTop {
${StyledModal.classSelector} {
transform: translate(0, -100vh);
}
&[data-open='true'] {
${StyledModal.classSelector} {
transform: translate(0);
}
}
}
&.scaleUp {
${StyledModal.classSelector} {
transform: scale(0.9);
}
&[data-open='true'] {
${StyledModal.classSelector} {
transform: scale(1);
}
}
}
&[data-type='tail'] {
justify-content: flex-end;
${StyledModal.classSelector} {
width: 420px;
height: 100%;
border-radius: 0;
overflow: hidden auto;
}
}
&[data-type='form'] {
${StyledModal.classSelector} {
width: 496px;
height: 548px;
max-height: 100%;
overflow-y: auto;
${utils.MediaQueries.mbDown} {
width: 340px;
}
}
}
&[data-type='video'] {
${StyledModal.classSelector} {
height: 100%;
max-height: 539px;
${utils.MediaQueries.mbDown} {
height: 192px;
width: 100%;
height: 100%;
border-radius: ${miscTheme.theme.borderRadius};
max-height: 192px;
}
}
}
&[data-type='confirm'] {
${StyledModal.classSelector} {
width: 100%;
max-width: 407px;
${utils.MediaQueries.mbDown} {
width: calc(100% - 32px);
max-width: calc(100% - 32px);
}
}
}
`;
const StyledModalMask = styled__default["default"].div `
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
align-items: center;
&[data-open='false'] {
display: none;
}
&[data-type='video'] {
background-color: ${miscTheme.theme.colors.secondaryDark};
}
`;
const MODAL_ROOT_ID = 'hhg-modals';
const getModalsRoot = () => {
let el = document.getElementById(MODAL_ROOT_ID);
if (!el) {
el = document.createElement('div');
el.setAttribute('id', MODAL_ROOT_ID);
document.body.append(el);
}
return el;
};
const cleanUpModalShow = () => {
const selector = '.hhg-modal[data-open="true"]';
const remainingPopupOpened = document.querySelectorAll(selector);
// Remove the opening class if there are only 1 popup is shown
if (remainingPopupOpened.length < 1) {
document.body.classList.remove('hhc-modal-show');
}
};
const cleanUpDisabledScroll = () => {
// Clear the overflow if there are only 1 popup is shown. useEffect runs after so the count number becomes zero
const selector = '.hhg-modal[data-open="true"]';
const remainingPopupOpened = document.querySelectorAll(selector);
if (remainingPopupOpened.length < 1) {
document.body.style.overflow = '';
document.body.style.paddingRight = '';
document.body.classList.remove('hhc-disabled-scroll');
}
};
/**
* @deprecated Consider to use at '@hhgtech/hhg-components/mantine'
*/
const Modal = ({ type = 'lead', closeIcon, isOpen = true, onClose, children, className = '', animationType = 'scaleUp', isStaticBackdrop = false, siteType, }) => {
const [mounted, setMounted] = React.useState(false);
const elRef = React.useRef(null);
const { width: scrollBarWidth } = useScrollbarSize.useScrollbarSize();
if (!elRef.current && mounted) {
elRef.current = document.createElement('div');
}
React.useEffect(() => {
setMounted(true);
return () => {
setMounted(false);
cleanUpModalShow();
cleanUpDisabledScroll();
};
}, []);
React.useEffect(() => {
if (mounted) {
const modalsRoot = getModalsRoot();
modalsRoot.appendChild(elRef.current);
return () => {
modalsRoot.removeChild(elRef.current);
};
}
}, [mounted]);
React.useEffect(() => {
if (isOpen) {
document.body.classList.add('hhc-modal-show');
}
else {
cleanUpModalShow();
}
}, [isOpen]);
React.useEffect(() => {
if (isOpen) {
document.body.style.overflow = 'hidden';
document.body.style.paddingRight = scrollBarWidth + 'px';
document.body.classList.add('hhc-disabled-scroll');
}
else {
cleanUpDisabledScroll();
}
}, [isOpen, scrollBarWidth]);
if (!mounted)
return null;
const classes = ['hhg-modal__wrapper', className, animationType]
.filter((s) => s)
.join(' ');
return ReactDOM.createPortal(React__default["default"].createElement(StyledModalWrapper, { className: classes, "data-open": isOpen, "data-type": type },
!isStaticBackdrop && (React__default["default"].createElement(StyledModalMask, { "data-open": isOpen, onClick: onClose, "data-type": type })),
!isStaticBackdrop && type === 'video' && !!closeIcon && (React__default["default"].createElement("div", { className: "hhg-modal__close", onClick: onClose }, closeIcon)),
React__default["default"].createElement(StyledModal, { className: "hhg-modal", "data-open": isOpen, "data-site-type": siteType },
React__default["default"].createElement("div", { className: type === 'video' ? 'hhg-modal__video' : 'hhg-modal__content' },
!!closeIcon && type !== 'video' && (React__default["default"].createElement("div", { className: "hhg-modal__close", onClick: onClose }, closeIcon)),
children))), elRef.current);
};
exports.Modal = Modal;