100 lines
2.7 KiB
TypeScript
100 lines
2.7 KiB
TypeScript
/**
|
|
* External dependencies
|
|
*/
|
|
import clsx from 'clsx';
|
|
import { useState, useRef, useEffect } from '@wordpress/element';
|
|
import { Spinner } from '@woocommerce/components';
|
|
import { useResizeObserver } from '@wordpress/compose';
|
|
import {
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore No types for this exist yet.
|
|
__unstableMotion as motion,
|
|
} from '@wordpress/components';
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import { getAdminSetting } from '~/utils/admin-settings';
|
|
import ResizableFrame from '~/customize-store/assembler-hub/resizable-frame';
|
|
import type { MainContentComponentProps } from '../xstate';
|
|
import './site-preview.scss';
|
|
|
|
export const SitePreviewPage = ( props: MainContentComponentProps ) => {
|
|
const siteUrl = getAdminSetting( 'siteUrl' ) + '?site-preview=1';
|
|
const [ isLoading, setIsLoading ] = useState( true );
|
|
const iframeRef = useRef< HTMLIFrameElement >( null );
|
|
const [ frameResizer, frameSize ] = useResizeObserver();
|
|
const [ isResizableFrameOversized, setIsResizableFrameOversized ] =
|
|
useState( false );
|
|
|
|
useEffect( () => {
|
|
const iframeContentWindow = iframeRef.current?.contentWindow;
|
|
|
|
const beforeUnloadHandler = () => {
|
|
setIsLoading( true );
|
|
};
|
|
|
|
if ( iframeContentWindow ) {
|
|
iframeContentWindow.addEventListener(
|
|
'beforeunload',
|
|
beforeUnloadHandler
|
|
);
|
|
}
|
|
return () => {
|
|
if ( iframeContentWindow ) {
|
|
iframeContentWindow.removeEventListener(
|
|
'beforeunload',
|
|
beforeUnloadHandler
|
|
);
|
|
}
|
|
};
|
|
// IsLoading is a dependency because we want to reset it when the iframe reloads.
|
|
}, [ iframeRef, setIsLoading, isLoading ] );
|
|
|
|
return (
|
|
<div
|
|
className={ clsx(
|
|
'launch-store-site-preview-page__container',
|
|
{ 'is-loading': isLoading },
|
|
props.className
|
|
) }
|
|
>
|
|
{ frameResizer }
|
|
{ !! frameSize.width && (
|
|
<motion.div
|
|
initial={ false }
|
|
layout="position"
|
|
className="launch-store-preview-layout__canvas"
|
|
>
|
|
<ResizableFrame
|
|
isReady={ ! isLoading }
|
|
isHandleVisibleByDefault={ false }
|
|
isFullWidth={ false }
|
|
defaultSize={ {
|
|
width: frameSize.width - 24,
|
|
height: frameSize.height,
|
|
} }
|
|
isOversized={ isResizableFrameOversized }
|
|
setIsOversized={ setIsResizableFrameOversized }
|
|
innerContentStyle={ {} }
|
|
>
|
|
{ isLoading && (
|
|
<div className="launch-store-site-preview-site__loading-overlay">
|
|
<Spinner />
|
|
</div>
|
|
) }
|
|
|
|
<iframe
|
|
ref={ iframeRef }
|
|
className="launch-store-site__preview-site-iframe"
|
|
src={ siteUrl }
|
|
title="Preview"
|
|
onLoad={ () => setIsLoading( false ) }
|
|
/>
|
|
</ResizableFrame>
|
|
</motion.div>
|
|
) }
|
|
</div>
|
|
);
|
|
};
|