irisrad-ui
Version:
UI elements developered for IRIS R&D Group Inc
181 lines (168 loc) • 5.56 kB
JavaScript
import React, { useState, useEffect, useRef, useCallback } from "react";
import "../../style/styles.css";
import PropTypes from "prop-types";
import { IrisButton } from "../irisButton/IrisButton";
// element ids
const MODAL_WRAPPER_ID = "iris-modal-wrapper";
const MODAL_CONTENT_ID = "iris-modal-content";
const MODAL_CONTENT_TITLE = "iris-modal-content-title";
const MODAL_CONTENT_BODY = "iris-modal-content-body";
const MODAL_CONTENT_ACTION_BTNS = "iris-modal-content-action-btns-container";
// wrapper css classes
const WRAPPER_BASE_CLASS = MODAL_WRAPPER_ID;
const WRAPPER_FADE_IN_CLASS = WRAPPER_BASE_CLASS + "__fade-in";
const WRAPPER_FADE_OUT_CLASS = WRAPPER_BASE_CLASS + "__fade-out";
const WRAPPER_DISMISS_CLASS = WRAPPER_FADE_OUT_CLASS + "__dismiss";
const WRAPPER_DISPLAY_CLASS = WRAPPER_FADE_IN_CLASS + "__display";
// content css classes
const CONTENT_BASE_CLASS = "iris-modal-content-wrapper";
const CONTENT_SLIDDOWN_CLASS = `${CONTENT_BASE_CLASS}--slide-down`;
const CONTENT_SLIDUP_CLASS = `${CONTENT_BASE_CLASS}--slide-up`;
const ANIMATION_TIME_IN_MILI = 200;
const fadeIn = (wrapper, content, timeoutFunctionRef, isFadeIn) => {
const modalWrapper = wrapper;
const modalContent = content;
let timeoutFunction = timeoutFunctionRef?.current;
if (timeoutFunction) {
clearTimeout(timeoutFunction);
timeoutFunction = null;
}
if (modalWrapper) {
const { classList: modalClassList } = modalWrapper;
const { classList: contentClassList } = modalContent;
if (modalClassList) {
modalClassList.remove(WRAPPER_DISPLAY_CLASS);
modalClassList.remove(WRAPPER_DISMISS_CLASS);
modalClassList.remove(WRAPPER_FADE_IN_CLASS);
modalClassList.remove(WRAPPER_FADE_OUT_CLASS);
contentClassList.remove(CONTENT_SLIDUP_CLASS);
contentClassList.remove(CONTENT_SLIDDOWN_CLASS);
if (isFadeIn) {
modalClassList.add(WRAPPER_DISPLAY_CLASS);
timeoutFunction = setTimeout(() => {
modalClassList.add(WRAPPER_FADE_IN_CLASS);
contentClassList.add(CONTENT_SLIDDOWN_CLASS);
}, 50);
} else {
modalClassList.add(WRAPPER_FADE_OUT_CLASS);
timeoutFunction = setTimeout(() => {
modalClassList.add(WRAPPER_DISMISS_CLASS);
contentClassList.add(CONTENT_SLIDUP_CLASS);
}, ANIMATION_TIME_IN_MILI);
}
}
}
};
export const IrisModal = ({
open,
onClose,
children,
className = "",
closeOnBackdrlpClicked,
...props
}) => {
const [show, setShow] = useState(false);
const modalWrapperRef = useRef();
const modalContentRef = useRef();
const timeoutFunctionRef = useRef(null);
const delayTimeoutFunctionRef = useRef(null);
const clearTimeoutFunctions = useCallback(() => {
if (timeoutFunctionRef?.current) {
clearTimeout(timeoutFunctionRef.current);
}
if (delayTimeoutFunctionRef?.current) {
clearTimeout(delayTimeoutFunctionRef.current);
}
}, [timeoutFunctionRef, delayTimeoutFunctionRef]);
useEffect(() => {
console.log(`showing`, show);
clearTimeoutFunctions();
if (show) {
fadeIn(
modalWrapperRef?.current,
modalContentRef?.current,
timeoutFunctionRef?.current,
show
);
}
}, [
clearTimeoutFunctions,
timeoutFunctionRef,
modalWrapperRef,
modalContentRef,
show,
]);
useEffect(() => {
console.log(`toggleing`, open);
clearTimeoutFunctions();
if (show) {
fadeIn(
modalWrapperRef?.current,
modalContentRef?.current,
timeoutFunctionRef?.current,
false
);
delayTimeoutFunctionRef.current = setTimeout(() => {
setShow(open);
}, ANIMATION_TIME_IN_MILI);
} else {
setShow(open);
}
}, [clearTimeoutFunctions, timeoutFunctionRef, open]);
let wrapperClass = WRAPPER_BASE_CLASS;
if (typeof className === "string" && className !== "") {
wrapperClass += " " + className;
}
let contentBaseClass = CONTENT_BASE_CLASS;
if (!children) {
contentBaseClass += " default-width";
}
if (!show) return null;
return (
<div
ref={modalWrapperRef}
className={wrapperClass}
onClick={(e) => {
if (closeOnBackdrlpClicked && onClose) {
onClose();
}
}}
{...props}
>
<div
ref={modalContentRef}
className={contentBaseClass}
onClick={(e) => {
e.stopPropagation();
}}
>
{children ? (
children
) : (
<div className={`${CONTENT_BASE_CLASS}__container`}>
<h2 className={`${CONTENT_BASE_CLASS}__container__title`}>
default layout for title
</h2>
<h2 className={`${CONTENT_BASE_CLASS}__container__content`}>
default layout for content
</h2>
<div className={`${CONTENT_BASE_CLASS}__container__action-btns`}>
<IrisButton color="secondary" onClick={onClose}>
Cancel
</IrisButton>
<IrisButton color="primary" onClick={onClose}>
okay
</IrisButton>
</div>
</div>
)}
</div>
</div>
);
};
IrisModal.propTypes = {
className: PropTypes.string,
open: PropTypes.bool.isRequired,
onClose: PropTypes.func,
closeOnBackdrlpClicked: PropTypes.bool,
};