import React, { useEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import createCache from '@emotion/cache'; import { CacheProvider } from '@emotion/react'; import { useDialogContext, useDialogActions } from './dialogContext'; export const NewWindow = (props: React.PropsWithChildren) => { const newWindow = useRef(null); const [popup, setPopup] = useState(null); const { setContainer, onClose } = useDialogActions(); const container = useDialogContext((c) => c.container); useEffect(() => { // Create container element on client-side const div = document.createElement('div'); div.style.width = '100vw'; div.style.height = '100vh'; div.style.position = 'relative'; setContainer(div); }, []); useEffect(() => { // When container is ready if (container) { // Create window const win = window.open('', '', 'width=600,height=600,left=200,top=200'); if (!win) { return; } win.document.title = 'Tolgee - Translate Text'; if (!win.document) { alert('Please allow popups to open new window.'); } // @ts-ignore newWindow.current = win; // Append container win.document.body.style.margin = '0px'; win.document.body.appendChild(container); const onExit = () => { setContainer(undefined); win.close(); onClose(); }; win.onbeforeunload = () => { setContainer(undefined); onClose(); }; const onKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { onClose(); } }; const onBeforeUnload = () => { onExit(); }; win.document.addEventListener('keydown', onKeyDown, true); window.addEventListener('beforeunload', onBeforeUnload, true); setPopup(win); return () => { win.document.removeEventListener('keydown', onKeyDown, true); window.removeEventListener('beforeunload', onBeforeUnload, true); setContainer(undefined); newWindow.current?.close(); setPopup(null); }; } }, [container]); useEffect(() => { popup?.focus(); }); const styleCache: any = React.useMemo(() => { // styles insertion point in popup head const head = popup?.document.head; return createCache({ key: 'external', container: head, prepend: true, }); }, [popup]); return popup && container ? createPortal( {props.children}, container ) : null; };