2020-12-17 20:53:22 +00:00
|
|
|
import GlobalInfos from '../../utils/GlobalInfos';
|
2020-12-11 18:23:13 +00:00
|
|
|
import style from './PopupBase.module.css';
|
|
|
|
import {Line} from '../PageTitle/PageTitle';
|
2021-01-22 21:05:21 +00:00
|
|
|
import React, {RefObject} from 'react';
|
2021-01-28 19:50:26 +00:00
|
|
|
import {addKeyHandler, removeKeyHandler} from '../../utils/ShortkeyHandler';
|
2021-01-22 21:05:21 +00:00
|
|
|
|
2021-03-14 14:51:53 +00:00
|
|
|
interface Props {
|
2021-01-22 21:05:21 +00:00
|
|
|
width?: string;
|
|
|
|
height?: string;
|
|
|
|
banner?: JSX.Element;
|
|
|
|
title: string;
|
2021-01-28 19:50:26 +00:00
|
|
|
onHide: () => void;
|
|
|
|
ParentSubmit?: () => void;
|
2021-01-22 21:05:21 +00:00
|
|
|
}
|
2020-12-11 18:23:13 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* wrapper class for generic types of popups
|
|
|
|
*/
|
2021-03-14 14:51:53 +00:00
|
|
|
class PopupBase extends React.Component<Props> {
|
2021-01-22 21:05:21 +00:00
|
|
|
private wrapperRef: RefObject<HTMLDivElement>;
|
2021-03-14 14:51:53 +00:00
|
|
|
private framedimensions: {minHeight: string | undefined; width: string | undefined; height: string | undefined};
|
2021-01-22 21:05:21 +00:00
|
|
|
|
2021-03-14 14:51:53 +00:00
|
|
|
constructor(props: Props) {
|
2020-12-11 18:23:13 +00:00
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.state = {items: []};
|
|
|
|
|
|
|
|
this.wrapperRef = React.createRef();
|
|
|
|
|
|
|
|
this.handleClickOutside = this.handleClickOutside.bind(this);
|
|
|
|
this.keypress = this.keypress.bind(this);
|
|
|
|
|
|
|
|
// parse style props
|
|
|
|
this.framedimensions = {
|
2021-03-14 14:51:53 +00:00
|
|
|
width: this.props.width ? this.props.width : undefined,
|
|
|
|
height: this.props.height ? this.props.height : undefined,
|
|
|
|
minHeight: this.props.height ? this.props.height : undefined
|
2020-12-11 18:23:13 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-01-22 21:05:21 +00:00
|
|
|
componentDidMount(): void {
|
2020-12-11 18:23:13 +00:00
|
|
|
document.addEventListener('mousedown', this.handleClickOutside);
|
2021-01-28 19:50:26 +00:00
|
|
|
addKeyHandler(this.keypress);
|
2020-12-11 18:23:13 +00:00
|
|
|
|
|
|
|
// add element drag drop events
|
|
|
|
if (this.wrapperRef != null) {
|
|
|
|
this.dragElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-22 21:05:21 +00:00
|
|
|
componentWillUnmount(): void {
|
2020-12-11 18:23:13 +00:00
|
|
|
// remove the appended listeners
|
|
|
|
document.removeEventListener('mousedown', this.handleClickOutside);
|
2021-01-28 19:50:26 +00:00
|
|
|
removeKeyHandler(this.keypress);
|
2020-12-11 18:23:13 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:05:21 +00:00
|
|
|
render(): JSX.Element {
|
2020-12-11 18:23:13 +00:00
|
|
|
const themeStyle = GlobalInfos.getThemeStyle();
|
|
|
|
return (
|
|
|
|
<div style={this.framedimensions} className={[style.popup, themeStyle.thirdbackground].join(' ')} ref={this.wrapperRef}>
|
|
|
|
<div className={style.header}>
|
|
|
|
<div className={[style.title, themeStyle.textcolor].join(' ')}>{this.props.title}</div>
|
|
|
|
<div className={style.banner}>{this.props.banner}</div>
|
|
|
|
</div>
|
|
|
|
|
2021-03-14 14:51:53 +00:00
|
|
|
<Line />
|
|
|
|
<div className={style.content}>{this.props.children}</div>
|
2020-12-11 18:23:13 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-01-30 21:54:20 +01:00
|
|
|
* handle click on outside of element
|
2020-12-11 18:23:13 +00:00
|
|
|
*/
|
2021-01-22 21:05:21 +00:00
|
|
|
handleClickOutside(event: MouseEvent): void {
|
|
|
|
if (this.wrapperRef && this.wrapperRef.current && !this.wrapperRef.current.contains(event.target as Node)) {
|
2020-12-11 18:23:13 +00:00
|
|
|
this.props.onHide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* key event handling
|
|
|
|
* @param event keyevent
|
|
|
|
*/
|
2021-01-22 21:05:21 +00:00
|
|
|
keypress(event: KeyboardEvent): void {
|
2020-12-11 18:23:13 +00:00
|
|
|
// hide if escape is pressed
|
|
|
|
if (event.key === 'Escape') {
|
|
|
|
this.props.onHide();
|
2021-01-28 19:50:26 +00:00
|
|
|
} else if (event.key === 'Enter') {
|
|
|
|
// call a parentsubmit if defined
|
2021-03-14 14:51:53 +00:00
|
|
|
if (this.props.ParentSubmit) {
|
|
|
|
this.props.ParentSubmit();
|
|
|
|
}
|
2020-12-11 18:23:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* make the element drag and droppable
|
|
|
|
*/
|
2021-01-22 21:05:21 +00:00
|
|
|
dragElement(): void {
|
2021-03-14 14:51:53 +00:00
|
|
|
let xOld = 0,
|
|
|
|
yOld = 0;
|
2020-12-11 18:23:13 +00:00
|
|
|
|
|
|
|
const elmnt = this.wrapperRef.current;
|
2021-03-14 14:51:53 +00:00
|
|
|
if (elmnt === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (elmnt.firstChild === null) {
|
|
|
|
return;
|
|
|
|
}
|
2020-12-11 18:23:13 +00:00
|
|
|
|
2021-01-22 21:05:21 +00:00
|
|
|
(elmnt.firstChild as HTMLDivElement).onmousedown = dragMouseDown;
|
2020-12-11 18:23:13 +00:00
|
|
|
|
2021-01-22 21:05:21 +00:00
|
|
|
function dragMouseDown(e: MouseEvent): void {
|
2020-12-11 18:23:13 +00:00
|
|
|
e.preventDefault();
|
|
|
|
// get the mouse cursor position at startup:
|
|
|
|
xOld = e.clientX;
|
|
|
|
yOld = e.clientY;
|
|
|
|
document.onmouseup = closeDragElement;
|
|
|
|
// call a function whenever the cursor moves:
|
|
|
|
document.onmousemove = elementDrag;
|
|
|
|
}
|
|
|
|
|
2021-01-22 21:05:21 +00:00
|
|
|
function elementDrag(e: MouseEvent): void {
|
2020-12-11 18:23:13 +00:00
|
|
|
e.preventDefault();
|
|
|
|
// calculate the new cursor position:
|
|
|
|
const dx = xOld - e.clientX;
|
|
|
|
const dy = yOld - e.clientY;
|
|
|
|
xOld = e.clientX;
|
|
|
|
yOld = e.clientY;
|
|
|
|
// set the element's new position:
|
2021-03-14 14:51:53 +00:00
|
|
|
if (elmnt === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
elmnt.style.top = elmnt.offsetTop - dy + 'px';
|
|
|
|
elmnt.style.left = elmnt.offsetLeft - dx + 'px';
|
2020-12-11 18:23:13 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:05:21 +00:00
|
|
|
function closeDragElement(): void {
|
2020-12-11 18:23:13 +00:00
|
|
|
// stop moving when mouse button is released:
|
|
|
|
document.onmouseup = null;
|
|
|
|
document.onmousemove = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default PopupBase;
|