* improve transform classic product template UX

* improve layout

* not update deps

* improve logic

* add bold

* fix height and width preview on hover

* fix label

* improve logic for revert button

* fix regression
This commit is contained in:
Luigi Teschio 2023-05-10 13:02:33 +02:00 committed by GitHub
parent b12cfd2d6a
commit b15cb932fb
11 changed files with 485 additions and 49 deletions

View File

@ -19,7 +19,7 @@ import {
} from '../product-query/constants'; } from '../product-query/constants';
import { VARIATION_NAME as productsVariationName } from '../product-query/variations/product-query'; import { VARIATION_NAME as productsVariationName } from '../product-query/variations/product-query';
import { createArchiveTitleBlock, createRowBlock } from './utils'; import { createArchiveTitleBlock, createRowBlock } from './utils';
import { type InheritedAttributes } from './types'; import { OnClickCallbackParameter, type InheritedAttributes } from './types';
const createProductsBlock = ( inheritedAttributes: InheritedAttributes ) => const createProductsBlock = ( inheritedAttributes: InheritedAttributes ) =>
createBlock( createBlock(
@ -71,7 +71,7 @@ const getDescriptionAllowingConversion = ( templateTitle: string ) =>
sprintf( sprintf(
/* translators: %s is the template title */ /* translators: %s is the template title */
__( __(
"This block serves as a placeholder for your %s. We recommend upgrading to the Products block for more features to edit your products visually. Don't worry, you can always revert back.", 'Transform this template into multiple blocks so you can add, remove, reorder, and customize your %s template.',
'woo-gutenberg-products-block' 'woo-gutenberg-products-block'
), ),
templateTitle templateTitle
@ -96,17 +96,69 @@ const getDescription = ( templateTitle: string, canConvert: boolean ) => {
}; };
const getButtonLabel = () => const getButtonLabel = () =>
__( 'Upgrade to Products block', 'woo-gutenberg-products-block' ); __( 'Transform into blocks', 'woo-gutenberg-products-block' );
const onClickCallback = ( {
clientId,
attributes,
getBlocks,
replaceBlock,
selectBlock,
}: OnClickCallbackParameter ) => {
replaceBlock( clientId, getBlockifiedTemplate( attributes ) );
const blocks = getBlocks();
const groupBlock = blocks.find(
( block ) =>
block.name === 'core/group' &&
block.innerBlocks.some(
( innerBlock ) =>
innerBlock.name === 'woocommerce/store-notices'
)
);
if ( groupBlock ) {
selectBlock( groupBlock.clientId );
}
};
const onClickCallbackWithTermDescription = ( {
clientId,
attributes,
getBlocks,
replaceBlock,
selectBlock,
}: OnClickCallbackParameter ) => {
replaceBlock( clientId, getBlockifiedTemplate( attributes, true ) );
const blocks = getBlocks();
const groupBlock = blocks.find(
( block ) =>
block.name === 'core/group' &&
block.innerBlocks.some(
( innerBlock ) =>
innerBlock.name === 'woocommerce/store-notices'
)
);
if ( groupBlock ) {
selectBlock( groupBlock.clientId );
}
};
export const blockifiedProductCatalogConfig = { export const blockifiedProductCatalogConfig = {
getBlockifiedTemplate, getBlockifiedTemplate,
isConversionPossible, isConversionPossible,
getDescription, getDescription,
getButtonLabel, getButtonLabel,
onClickCallback,
}; };
export const blockifiedProductTaxonomyConfig = { export const blockifiedProductTaxonomyConfig = {
getBlockifiedTemplate: getBlockifiedTemplateWithTermDescription, getBlockifiedTemplate: getBlockifiedTemplateWithTermDescription,
onClickCallback: onClickCallbackWithTermDescription,
isConversionPossible, isConversionPossible,
getDescription, getDescription,
getButtonLabel, getButtonLabel,

View File

@ -1,12 +1,14 @@
:where(.wp-block-woocommerce-legacy-template) { :where(.wp-block-woocommerce-legacy-template) {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
max-width: 1000px;
} }
.wp-block-woocommerce-classic-template__placeholder-copy { .wp-block-woocommerce-classic-template__placeholder-copy {
display: flex;
flex-direction: column;
max-width: 900px; max-width: 900px;
margin-bottom: 30px; width: 400px;
margin: auto;
} }
.wp-block-woocommerce-classic-template__placeholder-warning { .wp-block-woocommerce-classic-template__placeholder-warning {
@ -15,9 +17,12 @@
} }
.wp-block-woocommerce-classic-template__placeholder-wireframe { .wp-block-woocommerce-classic-template__placeholder-wireframe {
width: 100%;
height: 250px; height: 250px;
background: #e5e5e5; background: #e5e5e5;
display: flex;
flex-wrap: wrap;
gap: $gap-large;
margin: auto;
@media only screen and (min-width: 768px) { @media only screen and (min-width: 768px) {
height: auto; height: auto;
@ -27,7 +32,7 @@
.wp-block-woocommerce-classic-template__placeholder .wp-block-woocommerce-classic-template__placeholder-image { .wp-block-woocommerce-classic-template__placeholder .wp-block-woocommerce-classic-template__placeholder-image {
display: none; display: none;
width: 100%; width: 400px;
height: auto; height: auto;
@media only screen and (min-width: 768px) { @media only screen and (min-width: 768px) {
@ -35,14 +40,18 @@
} }
} }
.wp-block-woocommerce-classic-template__placeholder-wireframe {
display: flex;
flex-direction: column;
}
.wp-block-woocommerce-classic-template__placeholder-migration-button-container { .wp-block-woocommerce-classic-template__placeholder-migration-button-container {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin: 0 auto; margin: 0 auto;
} }
.wp-block-woocommerce-classic-template__placeholder-copy__icon-container {
display: flex;
align-items: center;
gap: $gap-small;
span {
@include font-size(larger);
}
}

View File

@ -2,6 +2,8 @@
* External dependencies * External dependencies
*/ */
import { import {
BlockInstance,
createBlock,
getBlockType, getBlockType,
registerBlockType, registerBlockType,
unregisterBlockType, unregisterBlockType,
@ -11,12 +13,18 @@ import {
isExperimentalBuild, isExperimentalBuild,
WC_BLOCKS_IMAGE_URL, WC_BLOCKS_IMAGE_URL,
} from '@woocommerce/block-settings'; } from '@woocommerce/block-settings';
import { useBlockProps } from '@wordpress/block-editor'; import {
import { Button, Placeholder } from '@wordpress/components'; useBlockProps,
BlockPreview,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { Button, Placeholder, Popover } from '@wordpress/components';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { box, Icon } from '@wordpress/icons'; import { box, Icon } from '@wordpress/icons';
import { select, useDispatch, subscribe } from '@wordpress/data'; import { useDispatch, subscribe, useSelect, select } from '@wordpress/data';
import { useEffect } from '@wordpress/element'; import { useEffect, useMemo, useState } from '@wordpress/element';
import { store as noticesStore } from '@wordpress/notices';
import { useEntityRecord } from '@wordpress/core-data';
/** /**
* Internal dependencies * Internal dependencies
@ -47,6 +55,7 @@ const blockifiedFallbackConfig = {
getBlockifiedTemplate: () => [], getBlockifiedTemplate: () => [],
getDescription: () => '', getDescription: () => '',
getButtonLabel: () => '', getButtonLabel: () => '',
onClickCallback: () => void 0,
}; };
const conversionConfig: { [ key: string ]: BlockifiedTemplateConfig } = { const conversionConfig: { [ key: string ]: BlockifiedTemplateConfig } = {
@ -57,19 +66,53 @@ const conversionConfig: { [ key: string ]: BlockifiedTemplateConfig } = {
fallback: blockifiedFallbackConfig, fallback: blockifiedFallbackConfig,
}; };
const pickBlockClientIds = ( blocks: Array< BlockInstance > ) =>
blocks.reduce< Array< string > >( ( acc, block ) => {
if ( block.name === 'core/template-part' ) {
return acc;
}
return [ ...acc, block.clientId ];
}, [] );
const Edit = ( { const Edit = ( {
clientId, clientId,
attributes, attributes,
setAttributes, setAttributes,
}: BlockEditProps< Attributes > ) => { }: BlockEditProps< Attributes > ) => {
const { replaceBlock } = useDispatch( 'core/block-editor' ); const { replaceBlock, selectBlock, replaceBlocks } =
useDispatch( blockEditorStore );
const { getBlocks, editedPostId } = useSelect( ( sel ) => {
return {
getBlocks: sel( blockEditorStore ).getBlocks,
editedPostId: sel( 'core/edit-site' ).getEditedPostId(),
};
}, [] );
const template = useEntityRecord< {
slug: string;
title: {
rendered?: string;
row: string;
};
} >( 'postType', 'wp_template', editedPostId );
const { createInfoNotice } = useDispatch( noticesStore );
const blocks = getBlocks();
const clientIds = useMemo( () => {
pickBlockClientIds( blocks );
}, [ blocks ] );
const blockProps = useBlockProps(); const blockProps = useBlockProps();
const templateDetails = getTemplateDetailsBySlug( const templateDetails = getTemplateDetailsBySlug(
attributes.template, attributes.template,
TEMPLATES TEMPLATES
); );
const templateTitle = templateDetails?.title ?? attributes.template; const templateTitle =
template.record?.title.rendered?.toLowerCase() ?? attributes.template;
const templatePlaceholder = templateDetails?.placeholder ?? 'fallback'; const templatePlaceholder = templateDetails?.placeholder ?? 'fallback';
const templateType = templateDetails?.type ?? 'fallback'; const templateType = templateDetails?.type ?? 'fallback';
@ -83,40 +126,128 @@ const Edit = ( {
); );
const { const {
getBlockifiedTemplate,
isConversionPossible, isConversionPossible,
getDescription, getDescription,
getButtonLabel, getButtonLabel,
onClickCallback,
getBlockifiedTemplate,
} = conversionConfig[ templateType ]; } = conversionConfig[ templateType ];
const canConvert = isConversionPossible(); const canConvert = isConversionPossible();
const placeholderDescription = getDescription( templateTitle, canConvert ); const placeholderDescription = getDescription( templateTitle, canConvert );
const [ isPopoverOpen, setIsPopoverOpen ] = useState( false );
return ( return (
<div { ...blockProps }> <div { ...blockProps }>
<Placeholder <Placeholder className="wp-block-woocommerce-classic-template__placeholder">
icon={ box }
label={ templateTitle }
className="wp-block-woocommerce-classic-template__placeholder"
>
<div className="wp-block-woocommerce-classic-template__placeholder-copy">
<p>{ placeholderDescription }</p>
</div>
<div className="wp-block-woocommerce-classic-template__placeholder-wireframe"> <div className="wp-block-woocommerce-classic-template__placeholder-wireframe">
{ canConvert && ( <div className="wp-block-woocommerce-classic-template__placeholder-copy">
<div className="wp-block-woocommerce-classic-template__placeholder-migration-button-container"> <div className="wp-block-woocommerce-classic-template__placeholder-copy__icon-container">
<Button <Icon icon={ box } />
isPrimary <span>
onClick={ () => { { __(
replaceBlock( 'Classic Product Template',
clientId, 'woo-gutenberg-products-block'
getBlockifiedTemplate( attributes ) ) }
); </span>
} }
text={ getButtonLabel() }
/>
</div> </div>
) } <p>{ placeholderDescription }</p>
{ canConvert && (
<div className="wp-block-woocommerce-classic-template__placeholder-migration-button-container">
<Button
isPrimary
onClick={ () => {
onClickCallback( {
clientId,
getBlocks,
attributes,
replaceBlock,
selectBlock,
} );
createInfoNotice(
__(
'Template transformed into blocks!',
'woo-gutenberg-products-block'
),
{
actions: [
{
label: __(
'Undo',
'woo-gutenberg-products-block'
),
onClick: () => {
replaceBlocks(
clientIds,
createBlock(
'core/group',
{
layout: {
inherit:
true,
type: 'constrained',
},
},
[
createBlock(
'woocommerce/legacy-template',
{
template:
attributes.template,
}
),
]
)
);
},
},
],
type: 'snackbar',
}
);
} }
onMouseEnter={ () =>
setIsPopoverOpen( true )
}
onMouseLeave={ () =>
setIsPopoverOpen( false )
}
text={ getButtonLabel() }
>
{ isPopoverOpen && (
<Popover
resize={ false }
placement="right-end"
>
<div
style={ {
minWidth: '250px',
width: '250px',
maxWidth: '250px',
minHeight: '300px',
height: '300px',
maxHeight: '300px',
cursor: 'pointer',
} }
>
<BlockPreview
blocks={ getBlockifiedTemplate(
attributes
) }
viewportWidth={ 1200 }
additionalStyles={ [
{
css: 'body { padding: 20px !important; height: fit-content !important; overflow:hidden}',
},
] }
/>
</div>
</Popover>
) }
</Button>
</div>
) }
</div>
<img <img
className="wp-block-woocommerce-classic-template__placeholder-image" className="wp-block-woocommerce-classic-template__placeholder-image"
src={ `${ WC_BLOCKS_IMAGE_URL }template-placeholders/${ templatePlaceholder }.svg` } src={ `${ WC_BLOCKS_IMAGE_URL }template-placeholders/${ templatePlaceholder }.svg` }

View File

@ -20,7 +20,7 @@ import {
} from '../product-query/constants'; } from '../product-query/constants';
import { VARIATION_NAME as productsVariationName } from '../product-query/variations/product-query'; import { VARIATION_NAME as productsVariationName } from '../product-query/variations/product-query';
import { createArchiveTitleBlock, createRowBlock } from './utils'; import { createArchiveTitleBlock, createRowBlock } from './utils';
import { type InheritedAttributes } from './types'; import { OnClickCallbackParameter, type InheritedAttributes } from './types';
const createNoResultsParagraph = () => const createNoResultsParagraph = () =>
createBlock( 'core/paragraph', { createBlock( 'core/paragraph', {
@ -118,7 +118,7 @@ const getDescriptionAllowingConversion = ( templateTitle: string ) =>
sprintf( sprintf(
/* translators: %s is the template title */ /* translators: %s is the template title */
__( __(
"This block serves as a placeholder for your %s. We recommend upgrading to the Products block for more features to edit your products visually. Don't worry, you can always revert back.", 'Transform this template into multiple blocks so you can add, remove, reorder, and customize your %s template.',
'woo-gutenberg-products-block' 'woo-gutenberg-products-block'
), ),
templateTitle templateTitle
@ -142,12 +142,38 @@ const getDescription = ( templateTitle: string, canConvert: boolean ) => {
return getDescriptionDisallowingConversion( templateTitle ); return getDescriptionDisallowingConversion( templateTitle );
}; };
const onClickCallback = ( {
clientId,
attributes,
getBlocks,
replaceBlock,
selectBlock,
}: OnClickCallbackParameter ) => {
replaceBlock( clientId, getBlockifiedTemplate( attributes ) );
const blocks = getBlocks();
const groupBlock = blocks.find(
( block ) =>
block.name === 'core/group' &&
block.innerBlocks.some(
( innerBlock ) =>
innerBlock.name === 'woocommerce/store-notices'
)
);
if ( groupBlock ) {
selectBlock( groupBlock.clientId );
}
};
const getButtonLabel = () => const getButtonLabel = () =>
__( 'Upgrade to Products block', 'woo-gutenberg-products-block' ); __( 'Transform into blocks', 'woo-gutenberg-products-block' );
export { export {
getBlockifiedTemplate, getBlockifiedTemplate,
isConversionPossible, isConversionPossible,
getDescription, getDescription,
getButtonLabel, getButtonLabel,
onClickCallback,
}; };

View File

@ -7,6 +7,11 @@ import { BlockInstance, createBlock } from '@wordpress/blocks';
import { VARIATION_NAME as PRODUCT_TITLE_VARIATION_NAME } from '@woocommerce/blocks/product-query/variations/elements/product-title'; import { VARIATION_NAME as PRODUCT_TITLE_VARIATION_NAME } from '@woocommerce/blocks/product-query/variations/elements/product-title';
import { VARIATION_NAME as PRODUCT_SUMMARY_VARIATION_NAME } from '@woocommerce/blocks/product-query/variations/elements/product-summary'; import { VARIATION_NAME as PRODUCT_SUMMARY_VARIATION_NAME } from '@woocommerce/blocks/product-query/variations/elements/product-summary';
/**
* Internal dependencies
*/
import { OnClickCallbackParameter } from './types';
const getBlockifiedTemplate = () => const getBlockifiedTemplate = () =>
[ [
createBlock( 'woocommerce/breadcrumbs' ), createBlock( 'woocommerce/breadcrumbs' ),
@ -58,7 +63,7 @@ const getDescriptionAllowingConversion = ( templateTitle: string ) =>
sprintf( sprintf(
/* translators: %s is the template title */ /* translators: %s is the template title */
__( __(
"This block serves as a placeholder for your %s. We recommend upgrading to the Single Products block for more features to edit your products visually. Don't worry, you can always revert back.", 'Transform this template into multiple blocks so you can add, remove, reorder, and customize your %s.',
'woo-gutenberg-products-block' 'woo-gutenberg-products-block'
), ),
templateTitle templateTitle
@ -83,14 +88,34 @@ const getDescription = ( templateTitle: string, canConvert: boolean ) => {
}; };
const getButtonLabel = () => const getButtonLabel = () =>
__( __( 'Transform into blocks', 'woo-gutenberg-products-block' );
'Upgrade to Blockified Single Product template',
'woo-gutenberg-products-block' const onClickCallback = ( {
clientId,
getBlocks,
replaceBlock,
selectBlock,
}: OnClickCallbackParameter ) => {
replaceBlock( clientId, getBlockifiedTemplate() );
const blocks = getBlocks();
const groupBlock = blocks.find(
( block ) =>
block.name === 'core/group' &&
block.innerBlocks.some(
( innerBlock ) => innerBlock.name === 'woocommerce/breadcrumbs'
)
); );
if ( groupBlock ) {
selectBlock( groupBlock.clientId );
}
};
export { export {
getBlockifiedTemplate, getBlockifiedTemplate,
isConversionPossible, isConversionPossible,
getDescription, getDescription,
getButtonLabel, getButtonLabel,
onClickCallback,
}; };

View File

@ -9,6 +9,14 @@ export type InheritedAttributes = {
align?: string; align?: string;
}; };
export type OnClickCallbackParameter = {
clientId: string;
attributes: Record< string, unknown >;
getBlocks: () => BlockInstance[];
replaceBlock: ( clientId: string, blocks: BlockInstance[] ) => void;
selectBlock: ( clientId: string ) => void;
};
export type BlockifiedTemplateConfig = { export type BlockifiedTemplateConfig = {
getBlockifiedTemplate: ( getBlockifiedTemplate: (
inheritedAttributes: InheritedAttributes inheritedAttributes: InheritedAttributes
@ -16,4 +24,5 @@ export type BlockifiedTemplateConfig = {
isConversionPossible: () => boolean; isConversionPossible: () => boolean;
getDescription: ( templateTitle: string, canConvert: boolean ) => string; getDescription: ( templateTitle: string, canConvert: boolean ) => string;
getButtonLabel: () => string; getButtonLabel: () => string;
onClickCallback: ( params: OnClickCallbackParameter ) => void;
}; };

View File

@ -5,6 +5,7 @@ import { getCategories, setCategories } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { woo } from '@woocommerce/icons'; import { woo } from '@woocommerce/icons';
import { Icon } from '@wordpress/icons'; import { Icon } from '@wordpress/icons';
import '@woocommerce/templates/revert-button';
/** /**
* Internal dependencies * Internal dependencies

View File

@ -0,0 +1,171 @@
/**
* External dependencies
*/
import { PluginTemplateSettingPanel } from '@wordpress/edit-site';
import { subscribe, select, useSelect, useDispatch } from '@wordpress/data';
import { BlockInstance, createBlock } from '@wordpress/blocks';
import { Button, PanelBody } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { createInterpolateElement, useMemo } from '@wordpress/element';
import { useEntityRecord } from '@wordpress/core-data';
import { store as blockEditorStore } from '@wordpress/block-editor';
// @ts-expect-error: @wordpress/plugin is typed in the newer versions
// eslint-disable-next-line @woocommerce/dependency-group
import {
registerPlugin,
unregisterPlugin,
getPlugin,
} from '@wordpress/plugins';
/**
* Internal dependencies
*/
import './style.scss';
const hasLegacyTemplateBlock = ( blocks: Array< BlockInstance > ): boolean => {
return blocks.some( ( block ) => {
return (
block.name === 'woocommerce/legacy-template' ||
hasLegacyTemplateBlock( block.innerBlocks )
);
} );
};
const pickBlockClientIds = ( blocks: Array< BlockInstance > ) =>
blocks.reduce< Array< string > >( ( acc, block ) => {
if ( block.name === 'core/template-part' ) {
return acc;
}
return [ ...acc, block.clientId ];
}, [] );
const RevertClassicTemplateButton = () => {
const { blocks, editedPostId } = useSelect( ( sel ) => {
return {
blocks: sel( blockEditorStore ).getBlocks(),
editedPostId: sel( 'core/edit-site' ).getEditedPostId(),
};
}, [] );
const { replaceBlocks } = useDispatch( blockEditorStore );
const template = useEntityRecord< {
slug: string;
title: {
rendered?: string;
row: string;
};
} >( 'postType', 'wp_template', editedPostId );
const isLegacyTemplateBlockAdded = useMemo(
() => hasLegacyTemplateBlock( blocks ),
[ blocks ]
);
const clientIds = useMemo( () => pickBlockClientIds( blocks ), [ blocks ] );
return (
<>
{ ! isLegacyTemplateBlockAdded && (
<PluginTemplateSettingPanel>
<PanelBody className="wc-block-editor-revert-button-container">
<Button
variant="secondary"
onClick={ () => {
replaceBlocks(
clientIds,
createBlock(
'core/group',
{
layout: {
inherit: true,
type: 'constrained',
},
},
[
createBlock(
'woocommerce/legacy-template',
{
template:
template?.record?.slug,
}
),
]
)
);
} }
>
{ __(
'Revert to Classic Product Template',
'woo-gutenberg-products-block'
) }
</Button>
<span>
{ createInterpolateElement(
__(
`The <strongText /> template doesnt allow for reordering or customizing blocks, but might work better with your extensions`,
'woo-gutenberg-products-block'
),
{
strongText: (
<strong>
{ template?.record?.title
?.rendered ?? '' }
</strong>
),
}
) }
</span>
</PanelBody>
</PluginTemplateSettingPanel>
) }
</>
);
};
const templateSlugs = [
'single-product',
'archive-product',
'product-search-results',
'taxonomy-product_cat',
'taxonomy-product_tag',
'taxonomy-product_attribute',
];
const REVERT_BUTTON_PLUGIN_NAME = 'woocommerce-blocks-revert-button-templates';
let currentTemplateId: string | undefined;
subscribe( () => {
const previousTemplateId = currentTemplateId;
const store = select( 'core/edit-site' );
currentTemplateId = store.getEditedPostId();
if ( previousTemplateId === currentTemplateId ) {
return;
}
const isWooTemplate = templateSlugs.some( ( slug ) =>
currentTemplateId?.includes( slug )
);
const hasSupportForPluginTemplateSettingPanel =
PluginTemplateSettingPanel !== undefined;
if ( isWooTemplate && hasSupportForPluginTemplateSettingPanel ) {
if ( getPlugin( REVERT_BUTTON_PLUGIN_NAME ) ) {
return;
}
return registerPlugin( REVERT_BUTTON_PLUGIN_NAME, {
render: RevertClassicTemplateButton,
} );
}
if ( getPlugin( REVERT_BUTTON_PLUGIN_NAME ) === undefined ) {
return;
}
unregisterPlugin( REVERT_BUTTON_PLUGIN_NAME );
}, 'core/edit-site' );

View File

@ -0,0 +1,8 @@
.wc-block-editor-revert-button-container {
display: flex;
flex-direction: column;
gap: $gap;
span {
color: $gray-700;
}
}

View File

@ -89,6 +89,10 @@ const getAlias = ( options = {} ) => {
), ),
'@woocommerce/types': path.resolve( __dirname, `../assets/js/types/` ), '@woocommerce/types': path.resolve( __dirname, `../assets/js/types/` ),
'@woocommerce/utils': path.resolve( __dirname, `../assets/js/utils/` ), '@woocommerce/utils': path.resolve( __dirname, `../assets/js/utils/` ),
'@woocommerce/templates': path.resolve(
__dirname,
`../assets/js/templates/`
),
}; };
}; };

View File

@ -65,7 +65,7 @@
"@woocommerce/e2e-utils": [ "tests/e2e-pw/utils" ], "@woocommerce/e2e-utils": [ "tests/e2e-pw/utils" ],
"@woocommerce/e2e-types": [ "tests/e2e-pw/types" ], "@woocommerce/e2e-types": [ "tests/e2e-pw/types" ],
"@woocommerce/e2e-playwright-utils": [ "tests/e2e-pw/playwright-utils" ], "@woocommerce/e2e-playwright-utils": [ "tests/e2e-pw/playwright-utils" ],
"@woocommerce/templates/*": [ "assets/js/templates/*" ],
} }
} }
} }