import { setAttributes, setStyles, StylesDeclaration } from 'utils/set-dom-props'; import { createIframe } from 'utils/create-iframe'; import type { Profile } from 'common/types'; let root: HTMLDivElement | null = null; let iframe: HTMLIFrameElement | null = null; function removeIframe() { iframe?.parentNode?.removeChild(iframe); } function createElement( tagName: K, styles: StylesDeclaration, attrs?: Record ) { const element = document.createElement(tagName); setStyles(element, styles); setAttributes(element, attrs); return element; } function createFragment(params: Profile & Record) { removeIframe(); iframe = createIframe({ ...params, page: 'profile', styles: styles.iframe }); if (!root) { root = createElement('div', styles.root); document.body.appendChild(root); } root.appendChild(iframe); setStyles(root, styles.rootShowed); setTimeout(() => iframe?.focus()); } function animateAppear(): void { window.requestAnimationFrame(() => { if (!root || !iframe) { return; } setStyles(root, styles.rootAppear); }); } function animateDisappear(): Promise { return new Promise((resolve) => { function handleTransitionEnd() { resolve(); if (!root) { return; } setStyles(root, styles.rootHidden); root.removeEventListener('transitionend', handleTransitionEnd); } window.requestAnimationFrame(() => { if (!root || !iframe) { return; } setStyles(root, styles.rootDissapear); root.addEventListener('transitionend', handleTransitionEnd); }); }); } function handleKeydown(evt: KeyboardEvent) { console.log(evt.code); if (evt.code !== 'Escape') { return; } closeProfile(); } export function openProfile(params: Profile & Record) { setStyles(document.body, { overflow: 'hidden' }); createFragment(params); animateAppear(); window.addEventListener('keydown', handleKeydown); } export function closeProfile() { window.removeEventListener('keydown', handleKeydown); animateDisappear().then(() => { removeIframe(); document.body.style.removeProperty('overflow'); }); } const styles = { root: { display: 'none', position: 'fixed', top: 0, right: 0, bottom: 0, left: 0, width: '100%', height: '100%', transition: 'opacity 0.5s ease-in', background: 'rgba(0, 0, 0, .4)', opacity: 0, zIndex: 99999999, }, rootShowed: { display: 'block', }, rootHidden: { display: 'none', }, rootAppear: { opacity: '1', }, rootDissapear: { opacity: '0', transition: 'opacity 0.3s ease-out', }, iframe: { position: 'absolute', right: 0, width: '100%', height: '100%', }, };