85 lines
2.5 KiB
TypeScript
85 lines
2.5 KiB
TypeScript
import React from "react";
|
|
import classes from "./classes.module.scss";
|
|
import Footer from "./Elements/Footer";
|
|
import Header from "./Elements/Header";
|
|
|
|
import Loader from "./Elements/Loader";
|
|
import Typography, { ITypo } from "../Typography";
|
|
import CrossIcon from "@Assets/icons/cross.svg";
|
|
import Image from "next/image";
|
|
|
|
export type IProps = {
|
|
closeBtn?: boolean;
|
|
header?: string | JSX.Element;
|
|
footer?: JSX.Element;
|
|
textLoader?: string | JSX.Element;
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
hasTransparentBackground?: boolean;
|
|
hasContainerClosable?: boolean;
|
|
withSideBackground?: boolean;
|
|
children?: React.ReactNode;
|
|
animationDelay?: number;
|
|
};
|
|
|
|
type IState = {
|
|
willClose: boolean;
|
|
};
|
|
|
|
export default class Modal extends React.Component<IProps, IState> {
|
|
static defaultProps = {
|
|
animationDelay: 170
|
|
};
|
|
public rootRefElement = React.createRef<HTMLDivElement>();
|
|
constructor(props: IProps) {
|
|
super(props);
|
|
this.close = this.close.bind(this);
|
|
|
|
this.state = {
|
|
willClose: false
|
|
};
|
|
}
|
|
|
|
public override render(): JSX.Element | null {
|
|
if (!this.props.isOpen) return null;
|
|
const onClick = (this.props.hasContainerClosable && this.close) || (() => { });
|
|
return (
|
|
<div ref={this.rootRefElement} className={classes["root"]} data-side-background={this.props.withSideBackground} data-will-close={this.state.willClose.toString()}>
|
|
<div className={classes["background"]} onClick={this.close} />
|
|
<div
|
|
className={[classes["container"], this.props.hasTransparentBackground && classes["transparant-background"]].join(" ")}
|
|
onClick={onClick} >
|
|
{this.props.closeBtn && (
|
|
<div className={classes["cross"]}>
|
|
<Image alt="Unplugged" src={CrossIcon} className={classes["close-icon"]} onClick={this.close} />
|
|
</div>
|
|
)}
|
|
<div className={classes["sub-container"]}>
|
|
{this.props.header && <Header content={this.props.header} />}
|
|
|
|
<Typography typo={ITypo.P_16}>
|
|
<>{this.props.children ? this.props.children : <Loader text={this.props.textLoader} />}</>
|
|
</Typography>
|
|
{this.props.children && this.props.footer && <Footer content={this.props.footer} />}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
public override componentDidUpdate(): void {
|
|
this.rootRefElement.current?.style.setProperty("--animation-delay", this.props.animationDelay!.toString().concat("ms"));
|
|
}
|
|
|
|
protected close() {
|
|
if (this.state.willClose) return;
|
|
this.setState({ willClose: true })
|
|
window.setTimeout(() => {
|
|
this.setState({
|
|
willClose: false
|
|
})
|
|
this.props.onClose()
|
|
}, this.props.animationDelay)
|
|
}
|
|
}
|