88 lines
2.2 KiB
JavaScript
88 lines
2.2 KiB
JavaScript
import React from 'react';
|
|
import { findDOMNode } from 'react-dom';
|
|
|
|
let overlayedCount = 0;
|
|
|
|
const ID = 'openreplay-overlay';
|
|
const Z_BASE = 99990;
|
|
|
|
const overlay = document.createElement("div");
|
|
overlay.setAttribute('id', ID);
|
|
|
|
// TODO: use className (class attribute)
|
|
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
|
|
overlay.style.position = 'fixed';
|
|
overlay.style.left = 0;
|
|
overlay.style.right = 0;
|
|
overlay.style.bottom = 0;
|
|
overlay.style.top = 0;
|
|
overlay.style.zIndex = Z_BASE;
|
|
|
|
const withOverlay = (
|
|
overlayedName = 'overlayed',
|
|
clickHandlerName = 'onOverlayClick',
|
|
zIndex = 0,
|
|
) => BaseComponent => {
|
|
return class extends React.Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.baseRef = React.createRef();
|
|
if (props[ overlayedName ]) {
|
|
overlayedCount++;
|
|
}
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.renderOverlay();
|
|
this.setOverlayedStyles();
|
|
}
|
|
|
|
componentDidUpdate(prevProps) {
|
|
if (prevProps[ overlayedName ] !== this.props[ overlayedName ]) {
|
|
if (!this.props[ overlayedName ]) {
|
|
overlayedCount--;
|
|
}
|
|
if (this.props[ overlayedName ]) {
|
|
overlayedCount++;
|
|
}
|
|
this.renderOverlay();
|
|
this.setOverlayedStyles();
|
|
}
|
|
}
|
|
|
|
clickHandler = () => {
|
|
const clickHandler = this.props[ clickHandlerName ];
|
|
if (clickHandler) clickHandler();
|
|
}
|
|
|
|
renderOverlay() {
|
|
if (overlayedCount > 0) {
|
|
if (overlay.parentNode === null) {
|
|
document.body.appendChild(overlay);
|
|
}
|
|
if (this.props[ overlayedName ]) {
|
|
overlay.addEventListener('click', this.clickHandler);
|
|
}
|
|
} else if (overlay.parentNode !== null) {
|
|
overlay.parentNode.removeChild(overlay);
|
|
}
|
|
}
|
|
|
|
setOverlayedStyles() {
|
|
const baseRoot = findDOMNode(this.baseRef.current);
|
|
const overlayed = this.props[ overlayedName ];
|
|
const actualZIndex = Z_BASE + 1 + zIndex;
|
|
if (baseRoot) {
|
|
// TODO: care about styles rewriting case
|
|
baseRoot.style.position = 'relative';
|
|
baseRoot.style.zIndex = overlayed ? actualZIndex : 'initial';
|
|
}
|
|
}
|
|
|
|
render() {
|
|
return <BaseComponent { ...this.props } ref={ this.baseRef } />;
|
|
}
|
|
};
|
|
}
|
|
|
|
export default withOverlay;
|