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

87 lines
2.1 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-10 19:11:16 +02:00
const { disableDrag = false } = props;
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-10 19:11:16 +02:00
const left = ((element.parentElement.clientWidth - element.clientWidth) / 2);
const top = ((element.parentElement.clientHeight - element.clientHeight) / 2);
2021-04-28 19:47:57 +02:00
element.style.left = `${ left }px`;
element.style.top = `${ top }px`;
2021-04-21 22:32:31 +02:00
return () =>
{
const index = currentWindows.indexOf(element);
if(index >= 0) currentWindows.splice(index, 1);
}
}, [ elementRef ]);
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>
);
}