Files
OpenMediaCenter/src/elements/Popups/PopupBase.tsx
T

142 lines
4.4 KiB
TypeScript
Raw Normal View History

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
interface props {
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-01-22 21:05:21 +00:00
class PopupBase extends React.Component<props> {
private wrapperRef: RefObject<HTMLDivElement>;
private framedimensions: { minHeight: string | undefined; width: string | undefined; height: string | undefined };
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 = {
width: (this.props.width ? this.props.width : undefined),
2020-12-17 20:53:22 +00:00
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>
<Line/>
<div className={style.content}>
{this.props.children}
</div>
</div>
);
}
/**
* Alert if clicked on outside of element
*/
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
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 {
2020-12-11 18:23:13 +00:00
let xOld = 0, yOld = 0;
const elmnt = this.wrapperRef.current;
2020-12-29 19:39:30 +00:00
if (elmnt === null) return;
2021-01-22 21:05:21 +00:00
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-01-22 21:05:21 +00:00
if (elmnt === null) return;
2020-12-11 18:23:13 +00:00
elmnt.style.top = (elmnt.offsetTop - dy) + 'px';
elmnt.style.left = (elmnt.offsetLeft - dx) + 'px';
}
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;