woocommerce/plugins/woocommerce-admin/client/launch-your-store/hub/main-content/pages/site-preview.tsx

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>
);
};