nitro-react/src/hooks/draggable-window/DraggableWindow.tsx

90 lines
2.2 KiB
TypeScript
Raw Normal View History

2021-05-10 19:11:16 +02:00
import { FC, MouseEvent, useEffect, useRef } from 'react';
2021-04-19 18:34:31 +02:00
import Draggable from 'react-draggable';
import { DraggableWindowProps } from './DraggableWindow.types';
2021-04-21 22:32:31 +02:00
const currentWindows: HTMLDivElement[] = [];
2021-05-10 19:11:16 +02:00
export const DraggableWindow: FC<DraggableWindowProps> = props =>
2021-04-19 18:34:31 +02:00
{
2021-05-12 00:11:22 +02:00
const { disableDrag = false, noCenter = false } = props;
2021-05-10 19:11:16 +02:00
const elementRef = useRef<HTMLDivElement>();
2021-04-21 22:32:31 +02:00
function bringToTop(): void
{
let zIndex = 400;
for(const existingWindow of currentWindows)
{
zIndex += 1;
existingWindow.style.zIndex = zIndex.toString();
}
}
function onMouseDown(event: MouseEvent): void
{
2021-04-23 07:16:09 +02:00
const index = currentWindows.indexOf(elementRef.current);
if(index === -1)
{
currentWindows.push(elementRef.current);
}
else if(index === (currentWindows.length - 1)) return;
else if(index >= 0)
{
currentWindows.splice(index, 1);
currentWindows.push(elementRef.current);
}
2021-04-21 22:32:31 +02:00
bringToTop();
}
useEffect(() =>
{
2021-04-24 03:05:56 +02:00
if(!elementRef) return;
2021-04-21 22:32:31 +02:00
const element = elementRef.current;
currentWindows.push(element);
bringToTop();
2021-05-12 00:11:22 +02:00
if(!noCenter)
{
const left = ((document.body.clientWidth / 2) - (element.clientWidth / 2));
const top = ((document.body.clientHeight / 2) - (element.clientHeight / 2));
2021-04-28 19:47:57 +02:00
2021-05-12 00:11:22 +02:00
element.style.left = `${ left }px`;
element.style.top = `${ top }px`;
}
2021-04-28 19:47:57 +02:00
2021-04-21 22:32:31 +02:00
return () =>
{
const index = currentWindows.indexOf(element);
if(index >= 0) currentWindows.splice(index, 1);
}
2021-05-12 00:11:22 +02:00
}, [ elementRef, noCenter ]);
2021-04-21 22:32:31 +02:00
2021-05-10 19:11:16 +02:00
function getWindowContent(): JSX.Element
{
return (
2021-04-28 19:47:57 +02:00
<div ref={ elementRef } className="position-absolute draggable-window" onMouseDownCapture={ onMouseDown }>
2021-04-21 22:32:31 +02:00
{ props.children }
</div>
2021-05-10 19:11:16 +02:00
);
}
if(disableDrag) return getWindowContent();
return (
<Draggable handle={ props.handle } { ...props.draggableOptions }>
{ getWindowContent() }
2021-04-19 18:34:31 +02:00
</Draggable>
);
}