73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
|
import useRnd from "components/system/Window/RndWindow/useRnd";
|
||
|
import { useProcesses } from "contexts/process";
|
||
|
import { useCallback, useEffect, useMemo, useRef } from "react";
|
||
|
import { Rnd } from "react-rnd";
|
||
|
import { FOCUSABLE_ELEMENT, PREVENT_SCROLL } from "utils/constants";
|
||
|
import { haltEvent } from "utils/functions";
|
||
|
|
||
|
type RndWindowProps = {
|
||
|
id: string;
|
||
|
zIndex: number;
|
||
|
};
|
||
|
|
||
|
const reRouteFocus =
|
||
|
(focusElement?: HTMLElement) =>
|
||
|
(element?: Element): void => {
|
||
|
element?.setAttribute("tabindex", FOCUSABLE_ELEMENT.tabIndex.toString());
|
||
|
element?.addEventListener("contextmenu", haltEvent);
|
||
|
element?.addEventListener("mousedown", (event) => {
|
||
|
event.preventDefault();
|
||
|
focusElement?.focus(PREVENT_SCROLL);
|
||
|
});
|
||
|
};
|
||
|
|
||
|
const RndWindow: FC<RndWindowProps> = ({ children, id, zIndex }) => {
|
||
|
const {
|
||
|
linkElement,
|
||
|
processes: { [id]: process },
|
||
|
} = useProcesses();
|
||
|
const { Component, componentWindow, maximized, minimized } = process || {};
|
||
|
const rndRef = useRef<Rnd | null>(null);
|
||
|
const rndProps = useRnd(id);
|
||
|
const style = useMemo<React.CSSProperties>(
|
||
|
() => ({
|
||
|
pointerEvents: minimized ? "none" : undefined,
|
||
|
zIndex,
|
||
|
}),
|
||
|
[minimized, zIndex]
|
||
|
);
|
||
|
const linkComponentWindow = useCallback(
|
||
|
(rndEntry: Rnd) => {
|
||
|
rndRef.current = rndEntry;
|
||
|
|
||
|
const rndWindowElements =
|
||
|
rndEntry?.resizableElement?.current?.children || [];
|
||
|
const [windowContainer] = rndWindowElements as HTMLElement[];
|
||
|
|
||
|
if (Component && !componentWindow && windowContainer) {
|
||
|
linkElement(id, "componentWindow", windowContainer);
|
||
|
}
|
||
|
},
|
||
|
[Component, componentWindow, id, linkElement]
|
||
|
);
|
||
|
|
||
|
useEffect(() => {
|
||
|
const { current: currentWindow } = rndRef;
|
||
|
const rndWindowElements =
|
||
|
currentWindow?.resizableElement?.current?.children || [];
|
||
|
const [windowContainer, resizeHandleContainer] =
|
||
|
rndWindowElements as HTMLElement[];
|
||
|
const resizeHandles = [...(resizeHandleContainer?.children || [])];
|
||
|
|
||
|
resizeHandles.forEach(reRouteFocus(windowContainer));
|
||
|
}, [maximized]);
|
||
|
|
||
|
return (
|
||
|
<Rnd ref={linkComponentWindow} style={style} {...rndProps}>
|
||
|
{children}
|
||
|
</Rnd>
|
||
|
);
|
||
|
};
|
||
|
|
||
|
export default RndWindow;
|