[Customize your store] Fix site preview in transitional screen (#40588)
* Replace mshot image with preview editor frame in transitional screen * Add changelog * Fix test * Use current xstate to check if it is transitional page
This commit is contained in:
parent
a28a552bbf
commit
06ea7ae24a
|
@ -47,7 +47,8 @@ export type ScaledBlockPreviewProps = {
|
|||
};
|
||||
additionalStyles: string;
|
||||
onClickNavigationItem: ( event: MouseEvent ) => void;
|
||||
isNavigable: boolean;
|
||||
isNavigable?: boolean;
|
||||
isScrollable?: boolean;
|
||||
};
|
||||
|
||||
function ScaledBlockPreview( {
|
||||
|
@ -57,6 +58,7 @@ function ScaledBlockPreview( {
|
|||
additionalStyles,
|
||||
onClickNavigationItem,
|
||||
isNavigable = false,
|
||||
isScrollable = true,
|
||||
}: ScaledBlockPreviewProps ) {
|
||||
const { setLogoBlock } = useContext( LogoBlockContext );
|
||||
const [ fontFamilies ] = useGlobalSetting(
|
||||
|
@ -78,6 +80,7 @@ function ScaledBlockPreview( {
|
|||
<DisabledProvider value={ true }>
|
||||
<Iframe
|
||||
aria-hidden
|
||||
scrolling={ isScrollable ? 'yes' : 'no' }
|
||||
tabIndex={ -1 }
|
||||
readonly={ ! isNavigable }
|
||||
contentRef={ useRefEffect(
|
||||
|
|
|
@ -14,15 +14,16 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
|
|||
import { unlock } from '@wordpress/edit-site/build-module/lock-unlock';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import useSiteEditorSettings from '@wordpress/edit-site/build-module/components/block-editor/use-site-editor-settings';
|
||||
import { useQuery } from '@woocommerce/navigation';
|
||||
import { useContext, useCallback } from '@wordpress/element';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import BlockPreview from './block-preview';
|
||||
import { useCallback } from '@wordpress/element';
|
||||
import { useEditorBlocks } from './hooks/use-editor-blocks';
|
||||
import { useScrollOpacity } from './hooks/use-scroll-opacity';
|
||||
import { useQuery } from '@woocommerce/navigation';
|
||||
import { CustomizeStoreContext } from './';
|
||||
|
||||
const { useHistory } = unlock( routerPrivateApis );
|
||||
|
||||
|
@ -66,6 +67,7 @@ export const BlockEditor = ( {} ) => {
|
|||
const settings = useSiteEditorSettings();
|
||||
const [ blocks ] = useEditorBlocks();
|
||||
const urlParams = useQuery();
|
||||
const { currentState } = useContext( CustomizeStoreContext );
|
||||
|
||||
const scrollDirection =
|
||||
urlParams.path === '/customize-store/assembler-hub/footer'
|
||||
|
@ -124,6 +126,7 @@ export const BlockEditor = ( {} ) => {
|
|||
settings={ settings }
|
||||
additionalStyles={ '' }
|
||||
isNavigable={ false }
|
||||
isScrollable={ currentState !== 'transitionalScreen' }
|
||||
onClickNavigationItem={ onClickNavigationItem }
|
||||
// Don't use sub registry so that we can get the logo block from the main registry on the logo sidebar navigation screen component.
|
||||
useSubRegistry={ false }
|
||||
|
|
|
@ -59,9 +59,11 @@ type CustomizeStoreComponentProps = Parameters< CustomizeStoreComponent >[ 0 ];
|
|||
export const CustomizeStoreContext = createContext< {
|
||||
sendEvent: CustomizeStoreComponentProps[ 'sendEvent' ];
|
||||
context: Partial< CustomizeStoreComponentProps[ 'context' ] >;
|
||||
currentState: CustomizeStoreComponentProps[ 'currentState' ];
|
||||
} >( {
|
||||
sendEvent: () => {},
|
||||
context: {},
|
||||
currentState: 'assemblerHub',
|
||||
} );
|
||||
|
||||
export type events =
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
useViewportMatch,
|
||||
} from '@wordpress/compose';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useState } from '@wordpress/element';
|
||||
import { useState, useContext } from '@wordpress/element';
|
||||
import {
|
||||
// @ts-ignore No types for this exist yet.
|
||||
__unstableMotion as motion,
|
||||
|
@ -45,6 +45,8 @@ import { LogoBlockContext } from './logo-block-context';
|
|||
import ResizableFrame from './resizable-frame';
|
||||
import { OnboardingTour, useOnboardingTour } from './onboarding-tour';
|
||||
import { HighlightedBlockContextProvider } from './context/highlighted-block-context';
|
||||
import { Transitional } from '../transitional';
|
||||
import { CustomizeStoreContext } from './';
|
||||
|
||||
const { useGlobalStyle } = unlock( blockEditorPrivateApis );
|
||||
|
||||
|
@ -74,6 +76,24 @@ export const Layout = () => {
|
|||
const { record: template } = useEditedEntityRecord();
|
||||
const { id: templateId, type: templateType } = template;
|
||||
|
||||
const { sendEvent, currentState } = useContext( CustomizeStoreContext );
|
||||
|
||||
const editor = <Editor isLoading={ isEditorLoading } />;
|
||||
|
||||
if ( currentState === 'transitionalScreen' ) {
|
||||
return (
|
||||
<EntityProvider kind="root" type="site">
|
||||
<EntityProvider
|
||||
kind="postType"
|
||||
type={ templateType }
|
||||
id={ templateId }
|
||||
>
|
||||
<Transitional sendEvent={ sendEvent } editor={ editor } />
|
||||
</EntityProvider>
|
||||
</EntityProvider>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<LogoBlockContext.Provider
|
||||
value={ {
|
||||
|
@ -188,11 +208,7 @@ export const Layout = () => {
|
|||
backgroundColor,
|
||||
} }
|
||||
>
|
||||
<Editor
|
||||
isLoading={
|
||||
isEditorLoading
|
||||
}
|
||||
/>
|
||||
{ editor }
|
||||
</ResizableFrame>
|
||||
</ErrorBoundary>
|
||||
</motion.div>
|
||||
|
|
|
@ -25,11 +25,7 @@ import {
|
|||
} from './intro';
|
||||
import { DesignWithAi, events as designWithAiEvents } from './design-with-ai';
|
||||
import { AssemblerHub, events as assemblerHubEvents } from './assembler-hub';
|
||||
import {
|
||||
Transitional,
|
||||
events as transitionalEvents,
|
||||
services as transitionalServices,
|
||||
} from './transitional';
|
||||
import { events as transitionalEvents } from './transitional';
|
||||
import { findComponentMeta } from '~/utils/xstate/find-component';
|
||||
import {
|
||||
CustomizeStoreComponentMeta,
|
||||
|
@ -102,7 +98,6 @@ export const customizeStoreStateMachineActions = {
|
|||
|
||||
export const customizeStoreStateMachineServices = {
|
||||
...introServices,
|
||||
...transitionalServices,
|
||||
browserPopstateHandler,
|
||||
markTaskComplete,
|
||||
};
|
||||
|
@ -264,14 +259,6 @@ export const customizeStoreStateMachineDefinition = createMachine( {
|
|||
invoke: {
|
||||
src: 'markTaskComplete',
|
||||
onDone: {
|
||||
target: 'waitForSitePreview',
|
||||
},
|
||||
},
|
||||
},
|
||||
waitForSitePreview: {
|
||||
after: {
|
||||
// Wait for 5 seconds before redirecting to the transitional page. This is to ensure that the site preview image is refreshed.
|
||||
5000: {
|
||||
target: '#customizeStore.transitionalScreen',
|
||||
},
|
||||
},
|
||||
|
@ -279,8 +266,6 @@ export const customizeStoreStateMachineDefinition = createMachine( {
|
|||
},
|
||||
on: {
|
||||
FINISH_CUSTOMIZATION: {
|
||||
// Pre-fetch the site preview image for the site for transitional page.
|
||||
actions: [ 'prefetchSitePreview' ],
|
||||
target: '.postAssemblerHub',
|
||||
},
|
||||
GO_BACK_TO_DESIGN_WITH_AI: {
|
||||
|
@ -291,7 +276,7 @@ export const customizeStoreStateMachineDefinition = createMachine( {
|
|||
transitionalScreen: {
|
||||
entry: [ { type: 'updateQueryStep', step: 'transitional' } ],
|
||||
meta: {
|
||||
component: Transitional,
|
||||
component: AssemblerHub,
|
||||
},
|
||||
on: {
|
||||
GO_BACK_TO_HOME: {
|
||||
|
@ -368,6 +353,7 @@ export const CustomizeStoreController = ( {
|
|||
parentMachine={ service }
|
||||
sendEvent={ send }
|
||||
context={ state.context }
|
||||
currentState={ state.value }
|
||||
/>
|
||||
) : (
|
||||
<div />
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
/* eslint-disable @woocommerce/dependency-group */
|
||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import classNames from 'classnames';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
@ -10,31 +13,28 @@ import {
|
|||
// @ts-ignore No types for this exist yet.
|
||||
__unstableMotion as motion,
|
||||
} from '@wordpress/components';
|
||||
// @ts-ignore No types for this exist yet.
|
||||
import { useIsSiteEditorLoading } from '@wordpress/edit-site/build-module/components/layout/hooks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { SiteHub } from '../assembler-hub/site-hub';
|
||||
import { MShotsImage } from './mshots-image';
|
||||
import { ADMIN_URL } from '~/utils/admin-settings';
|
||||
|
||||
import './style.scss';
|
||||
export * as services from './services';
|
||||
|
||||
export type events = { type: 'GO_BACK_TO_HOME' };
|
||||
export const PREVIEW_IMAGE_OPTION = {
|
||||
vpw: 1200,
|
||||
vph: 742,
|
||||
w: 588,
|
||||
h: 363.58,
|
||||
requeue: true,
|
||||
};
|
||||
|
||||
export const Transitional = ( {
|
||||
editor,
|
||||
sendEvent,
|
||||
}: {
|
||||
editor: React.ReactNode;
|
||||
sendEvent: ( event: events ) => void;
|
||||
} ) => {
|
||||
const homeUrl: string = getSetting( 'homeUrl', '' );
|
||||
const isEditorLoading = useIsSiteEditorLoading();
|
||||
|
||||
return (
|
||||
<div className="woocommerce-customize-store__transitional">
|
||||
|
@ -70,16 +70,15 @@ export const Transitional = ( {
|
|||
{ __( 'Preview store', 'woocommerce' ) }
|
||||
</Button>
|
||||
|
||||
<div className="woocommerce-customize-store__transitional-site-img-container">
|
||||
<MShotsImage
|
||||
url={ homeUrl }
|
||||
alt={ __( 'Your store screenshot', 'woocommerce' ) }
|
||||
aria-labelledby={ __(
|
||||
'Your store screenshot',
|
||||
'woocommerce'
|
||||
) }
|
||||
options={ PREVIEW_IMAGE_OPTION }
|
||||
/>
|
||||
<div
|
||||
className={ classNames(
|
||||
'woocommerce-customize-store__transitional-site-preview-container',
|
||||
{
|
||||
'is-loading': isEditorLoading,
|
||||
}
|
||||
) }
|
||||
>
|
||||
{ editor }
|
||||
</div>
|
||||
<div className="woocommerce-customize-store__transitional-actions">
|
||||
<div className="woocommerce-customize-store__transitional-action">
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
// See https://github.com/Automattic/wp-calypso/blob/6923bed938911a931e722a1efa6fcbbf942677a9/packages/onboarding/src/mshots-image/index.tsx
|
||||
// TODO: @automattic/onboarding is not published to npm, so we can't use it here. We'll need to add the "requeue" option to MShotsOptions and we could remove this when it's published.
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { addQueryArgs } from '@wordpress/url';
|
||||
import classnames from 'classnames';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
|
||||
interface MShotsImageProps {
|
||||
url: string;
|
||||
alt: string;
|
||||
'aria-labelledby': string;
|
||||
options: MShotsOptions;
|
||||
scrollable?: boolean;
|
||||
}
|
||||
|
||||
export type MShotsOptions = {
|
||||
vpw: number;
|
||||
vph: number;
|
||||
w: number;
|
||||
h?: number;
|
||||
screen_height?: number;
|
||||
format?: 'png' | 'jpeg';
|
||||
requeue?: boolean;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
const debug = console.debug;
|
||||
|
||||
export function getMshotsUrl(
|
||||
targetUrl: string,
|
||||
options: MShotsOptions,
|
||||
count = 0
|
||||
): string {
|
||||
const mshotsUrl = 'https://s0.wp.com/mshots/v1/';
|
||||
const mshotsRequest = addQueryArgs(
|
||||
mshotsUrl + encodeURIComponent( targetUrl ),
|
||||
{
|
||||
...options,
|
||||
count,
|
||||
}
|
||||
);
|
||||
return mshotsRequest;
|
||||
}
|
||||
|
||||
const MAXTRIES = 10;
|
||||
|
||||
// This custom react hook returns undefined while the image is loading and
|
||||
// a HTMLImageElement (i.e. the class you get from `new Image()`) once loading
|
||||
// is complete.
|
||||
//
|
||||
// It also triggers a re-render (via setState()) when the value changes, so just
|
||||
// check if it's truthy and then treat it like any other Image.
|
||||
//
|
||||
// Note the loading may occur immediately and synchronously if the image is
|
||||
// already or may take up to several seconds if mshots has to generate and cache
|
||||
// new images.
|
||||
//
|
||||
// The calling code doesn't need to worry about the details except that you'll
|
||||
// want some sort of loading display.
|
||||
//
|
||||
// Inspired by https://stackoverflow.com/a/60458593
|
||||
const useMshotsImg = (
|
||||
src: string,
|
||||
options: MShotsOptions
|
||||
): HTMLImageElement | undefined => {
|
||||
const [ loadedImg, setLoadedImg ] = useState< HTMLImageElement >();
|
||||
const [ count, setCount ] = useState( 0 );
|
||||
const previousSrc = useRef( src );
|
||||
|
||||
const imgRef = useRef< HTMLImageElement >();
|
||||
const timeoutIdRef = useRef< number >();
|
||||
|
||||
const previousImg = useRef< HTMLImageElement >();
|
||||
const previousOptions = useRef< MShotsOptions >();
|
||||
// Oddly, we need to assign to current here after ref creation in order to
|
||||
// pass the equivalence check and avoid a spurious reset
|
||||
previousOptions.current = options;
|
||||
|
||||
// Note: Mshots doesn't care about the "count" param, but it is important
|
||||
// to browser caching. Getting this wrong looks like the url resolving
|
||||
// before the image is ready.
|
||||
useEffect( () => {
|
||||
// If there's been a "props" change we need to reset everything:
|
||||
if (
|
||||
options !== previousOptions.current ||
|
||||
( src !== previousSrc.current && imgRef.current )
|
||||
) {
|
||||
// Make sure an old image can't trigger a spurious state update
|
||||
debug( 'resetting mShotsUrl request' );
|
||||
if ( src !== previousSrc.current ) {
|
||||
debug( 'src changed\nfrom', previousSrc.current, '\nto', src );
|
||||
}
|
||||
if ( options !== previousOptions.current ) {
|
||||
debug(
|
||||
'options changed\nfrom',
|
||||
previousOptions.current,
|
||||
'\nto',
|
||||
options
|
||||
);
|
||||
}
|
||||
if ( previousImg.current && previousImg.current.onload ) {
|
||||
previousImg.current.onload = null;
|
||||
if ( timeoutIdRef.current ) {
|
||||
clearTimeout( timeoutIdRef.current );
|
||||
timeoutIdRef.current = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
setLoadedImg( undefined );
|
||||
setCount( 0 );
|
||||
previousImg.current = imgRef.current;
|
||||
|
||||
previousOptions.current = options;
|
||||
previousSrc.current = src;
|
||||
}
|
||||
|
||||
const srcUrl = getMshotsUrl( src, options, count );
|
||||
const newImage = new Image();
|
||||
newImage.onload = () => {
|
||||
// Detect default image (Don't request a 400x300 image).
|
||||
//
|
||||
// If this turns out to be a problem, it might help to know that the
|
||||
// http request status for the default is a 307. Unfortunately we
|
||||
// don't get the request through an img element so we'd need to
|
||||
// take a completely different approach using ajax.
|
||||
if (
|
||||
newImage.naturalWidth !== 400 ||
|
||||
newImage.naturalHeight !== 300
|
||||
) {
|
||||
// Note we're using the naked object here, not the ref, because
|
||||
// this is the callback on the image itself. We'd never want
|
||||
// the image to finish loading and set some other image.
|
||||
setLoadedImg( newImage );
|
||||
} else if ( count < MAXTRIES ) {
|
||||
// Only refresh 10 times
|
||||
// Triggers a target.src change with increasing timeouts
|
||||
timeoutIdRef.current = window.setTimeout(
|
||||
() => setCount( ( _count ) => _count + 1 ),
|
||||
count * 500
|
||||
);
|
||||
}
|
||||
};
|
||||
newImage.src = srcUrl;
|
||||
imgRef.current = newImage;
|
||||
|
||||
return () => {
|
||||
if ( imgRef.current && imgRef.current.onload ) {
|
||||
imgRef.current.onload = null;
|
||||
}
|
||||
clearTimeout( timeoutIdRef.current );
|
||||
};
|
||||
}, [ src, count, options ] );
|
||||
|
||||
return loadedImg;
|
||||
};
|
||||
|
||||
// For hover-scroll, we use a div with a background image (rather than an img element)
|
||||
// in order to use transitions between `top` and `bottom` on the
|
||||
// `background-position` property.
|
||||
// The "normal" top & bottom properties are problematic individually because we
|
||||
// don't know how big the images will be, and using both gets the
|
||||
// right positions but with no transition (as they're different properties).
|
||||
export const MShotsImage = ( {
|
||||
url,
|
||||
'aria-labelledby': labelledby,
|
||||
alt,
|
||||
options,
|
||||
scrollable = false,
|
||||
}: MShotsImageProps ) => {
|
||||
const maybeImage = useMshotsImg( url, options );
|
||||
const src: string = maybeImage?.src || '';
|
||||
const visible = !! src;
|
||||
const backgroundImage = maybeImage?.src && `url( ${ maybeImage?.src } )`;
|
||||
|
||||
const animationScrollSpeedInPixelsPerSecond = 400;
|
||||
const animationDuration =
|
||||
( maybeImage?.naturalHeight || 600 ) /
|
||||
animationScrollSpeedInPixelsPerSecond;
|
||||
|
||||
const scrollableStyles = {
|
||||
backgroundImage,
|
||||
transition: `background-position ${ animationDuration }s`,
|
||||
};
|
||||
|
||||
const style = {
|
||||
...( scrollable ? scrollableStyles : {} ),
|
||||
};
|
||||
|
||||
const className = classnames(
|
||||
'mshots-image__container',
|
||||
scrollable && 'hover-scroll',
|
||||
visible ? 'mshots-image-visible' : 'mshots-image__loader'
|
||||
);
|
||||
|
||||
// The "! visible" here is only to dodge a particularly specific css
|
||||
// rule effecting the placeholder while loading static images:
|
||||
// '.design-picker .design-picker__image-frame img { ..., height: auto }'
|
||||
return scrollable || ! visible ? (
|
||||
<div
|
||||
className={ className }
|
||||
style={ style }
|
||||
aria-labelledby={ labelledby }
|
||||
/>
|
||||
) : (
|
||||
<img
|
||||
{ ...{ className, style, src, alt } }
|
||||
aria-labelledby={ labelledby }
|
||||
alt={ alt }
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default MShotsImage;
|
|
@ -1,19 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { getMshotsUrl } from './mshots-image';
|
||||
import { PREVIEW_IMAGE_OPTION } from './';
|
||||
|
||||
export const fetchSitePreviewImage = async () => {
|
||||
const homeUrl: string = getSetting( 'homeUrl', '' );
|
||||
return window
|
||||
.fetch( getMshotsUrl( homeUrl, PREVIEW_IMAGE_OPTION ) )
|
||||
.catch( () => {
|
||||
// Ignore errors
|
||||
} );
|
||||
};
|
|
@ -67,25 +67,59 @@
|
|||
margin: 20px 0 0;
|
||||
}
|
||||
|
||||
.woocommerce-customize-store__transitional-site-img-container {
|
||||
width: 600px;
|
||||
height: 371px;
|
||||
.woocommerce-customize-store__transitional-site-preview-container {
|
||||
border-radius: 16px;
|
||||
margin-top: 50px;
|
||||
background: #f6f7f7;
|
||||
box-shadow: 0 6px 6px 0 rgba(0, 0, 0, 0.02), 0 13px 10px 0 rgba(0, 0, 0, 0.03), 0 15px 20px 0 rgba(0, 0, 0, 0.04);
|
||||
margin-top: 50px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 600px;
|
||||
height: 371px;
|
||||
|
||||
.mshots-image__loader {
|
||||
width: 600px;
|
||||
height: 371px;
|
||||
border-radius: 16px;
|
||||
div {
|
||||
position: relative;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
img {
|
||||
border-radius: 16px;
|
||||
.woocommerce-customize-store__edit-site-editor {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.woocommerce-customize-store__block-editor {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.interface-navigable-region {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.auto-block-preview__container {
|
||||
width: 588px;
|
||||
height: 363px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border-radius: 24px;
|
||||
width: 1176px;
|
||||
height: 726px;
|
||||
transform: scale(0.5);
|
||||
left: -50%;
|
||||
position: relative;
|
||||
top: -50%;
|
||||
}
|
||||
|
||||
&.is-loading {
|
||||
@include placeholder();
|
||||
|
||||
iframe {
|
||||
visibility: hidden;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,22 +167,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// mshots component
|
||||
.mshots-image__loader {
|
||||
@include placeholder();
|
||||
}
|
||||
|
||||
.mshots-image-visible {
|
||||
animation: fadein 300ms;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,13 +10,6 @@ import { recordEvent } from '@woocommerce/tracks';
|
|||
*/
|
||||
import { Transitional } from '../index';
|
||||
|
||||
jest.mock( '../mshots-image', () => ( {
|
||||
__esModule: true,
|
||||
MShotsImage: () => {
|
||||
return <img alt="preview-img" />;
|
||||
},
|
||||
} ) );
|
||||
|
||||
jest.mock( '../../assembler-hub/site-hub', () => ( {
|
||||
__esModule: true,
|
||||
SiteHub: () => {
|
||||
|
@ -24,6 +17,14 @@ jest.mock( '../../assembler-hub/site-hub', () => ( {
|
|||
},
|
||||
} ) );
|
||||
|
||||
jest.mock(
|
||||
'@wordpress/edit-site/build-module/components/layout/hooks',
|
||||
() => ( {
|
||||
__esModule: true,
|
||||
useIsSiteEditorLoading: jest.fn().mockReturnValue( false ),
|
||||
} )
|
||||
);
|
||||
|
||||
jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) );
|
||||
|
||||
describe( 'Transitional', () => {
|
||||
|
@ -45,8 +46,6 @@ describe( 'Transitional', () => {
|
|||
screen.getByText( /Your store looks great!/i )
|
||||
).toBeInTheDocument();
|
||||
|
||||
expect( screen.getByRole( 'img' ) ).toBeInTheDocument();
|
||||
|
||||
expect(
|
||||
screen.getByRole( 'button', {
|
||||
name: /Preview store/i,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { AnyInterpreter, Sender } from 'xstate';
|
||||
import { AnyInterpreter, Sender, StateValue } from 'xstate';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -13,6 +13,7 @@ export type CustomizeStoreComponent = ( props: {
|
|||
parentMachine: AnyInterpreter;
|
||||
sendEvent: Sender< customizeStoreStateMachineEvents >;
|
||||
context: customizeStoreStateMachineContext;
|
||||
currentState: StateValue;
|
||||
} ) => React.ReactElement | null;
|
||||
|
||||
export type CustomizeStoreComponentMeta = {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: fix
|
||||
|
||||
Fix customize your store site preview in transitional screen
|
Loading…
Reference in New Issue