Commit 2a2528a30bf for woocommerce
commit 2a2528a30bfd7732e5a5ad075ee7801c465ac20b
Author: Albert Juhé Lluveras <contact@albertjuhe.com>
Date: Tue Jul 14 11:59:47 2026 +0200
Introduce new upgrade warning to the Product Image Gallery block when used in the same template with the Add to Cart + Options block (#66552)
* Introduce new upgrade warning to the Product Image Gallery block when used in the same template with the Add to Cart + Options block
* Add changelog
* Remove only flag from test
* Use upgradeToBlockifiedProductGallery instead of replaceBlockWithProductGallery
* Merge notices
* Move edit utils file
* Update e2e test
diff --git a/plugins/woocommerce/changelog/update-product-image-gallery-upgrade-notice-with-add-to-cart-with-options b/plugins/woocommerce/changelog/update-product-image-gallery-upgrade-notice-with-add-to-cart-with-options
new file mode 100644
index 00000000000..f30eaa9067e
--- /dev/null
+++ b/plugins/woocommerce/changelog/update-product-image-gallery-upgrade-notice-with-add-to-cart-with-options
@@ -0,0 +1,4 @@
+Significance: patch
+Type: update
+
+Introduce new upgrade warning to the Product Image Gallery block when used in the same template with the Add to Cart + Options block
diff --git a/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/edit-utils.tsx b/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/edit-utils.tsx
new file mode 100644
index 00000000000..4189f4a78e0
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/edit-utils.tsx
@@ -0,0 +1,29 @@
+/**
+ * External dependencies
+ */
+import { createBlock } from '@wordpress/blocks';
+import { dispatch, select } from '@wordpress/data';
+import { findBlock } from '@woocommerce/utils';
+
+/**
+ * Internal dependencies
+ */
+import metadata from './block.json';
+
+export const upgradeToBlockifiedProductGallery = ( blockClientId: string ) => {
+ const blocks = select( 'core/block-editor' ).getBlocks();
+ const foundBlock = findBlock( {
+ blocks,
+ findCondition: ( block ) =>
+ block.name === metadata.name && block.clientId === blockClientId,
+ } );
+
+ if ( foundBlock ) {
+ const newBlock = createBlock( 'woocommerce/product-gallery' );
+
+ dispatch( 'core/block-editor' ).replaceBlock( blockClientId, newBlock );
+
+ return true;
+ }
+ return false;
+};
diff --git a/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/edit.tsx b/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/edit.tsx
index 1eb34533803..0a16bebcaba 100644
--- a/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/edit.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/edit.tsx
@@ -3,8 +3,10 @@
*/
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { Disabled } from '@wordpress/components';
+import { useSelect } from '@wordpress/data';
import { PLACEHOLDER_IMG_SRC } from '@woocommerce/settings';
import { BlockEditProps } from '@wordpress/blocks';
+import { findBlock } from '@woocommerce/utils';
/**
* Internal dependencies
@@ -33,11 +35,25 @@ const Placeholder = () => {
const Edit = ( props: BlockEditProps< Record< string, never > > ) => {
const blockProps = useBlockProps();
+ const hasAddToCartWithOptionsBlock = useSelect( ( select ) => {
+ const blocks = select( 'core/block-editor' ).getBlocks();
+
+ return !! findBlock( {
+ blocks,
+ findCondition: ( block ) =>
+ block.name === 'woocommerce/add-to-cart-with-options',
+ } );
+ }, [] );
return (
<div { ...blockProps }>
<InspectorControls>
- <UpgradeNotice blockClientId={ props.clientId } />
+ <UpgradeNotice
+ blockClientId={ props.clientId }
+ showAddToCartWithOptionsCompatibilityNotice={
+ hasAddToCartWithOptionsBlock
+ }
+ />
</InspectorControls>
<Disabled>
<Placeholder />
diff --git a/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/upgrade-notice.tsx b/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/upgrade-notice.tsx
index 84ef5da26b2..c4711ceb77b 100644
--- a/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/upgrade-notice.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/atomic/blocks/product-elements/product-image-gallery/upgrade-notice.tsx
@@ -3,48 +3,38 @@
*/
import { __ } from '@wordpress/i18n';
import { createInterpolateElement } from '@wordpress/element';
-import { select } from '@wordpress/data';
import { UpgradeDowngradeNotice } from '@woocommerce/editor-components/upgrade-downgrade-notice';
-import { findBlock } from '@woocommerce/utils';
/**
* Internal dependencies
*/
-import metadata from './block.json';
-import { replaceBlockWithProductGallery } from '../../../../blocks/product-gallery/edit-utils';
-
-const upgradeToBlockifiedProductGallery = ( blockClientId: string ) => {
- const blocks = select( 'core/block-editor' ).getBlocks();
- const foundBlock = findBlock( {
- blocks,
- findCondition: ( block ) =>
- block.name === metadata.name && block.clientId === blockClientId,
- } );
-
- if ( foundBlock ) {
- return replaceBlockWithProductGallery( foundBlock.clientId );
- }
- return false;
-};
+import { upgradeToBlockifiedProductGallery } from './edit-utils';
export const UpgradeNotice = ( {
blockClientId,
+ showAddToCartWithOptionsCompatibilityNotice,
}: {
blockClientId: string;
+ showAddToCartWithOptionsCompatibilityNotice: boolean;
} ) => {
- const notice = createInterpolateElement(
- __(
- 'Upgrade to the <strongText /> for more flexibility.',
- 'woocommerce'
- ),
- {
- strongText: (
- <strong>
- { __( `Product Gallery block`, 'woocommerce' ) }
- </strong>
- ),
- }
- );
+ const notice = showAddToCartWithOptionsCompatibilityNotice
+ ? __(
+ 'The classic Product Image Gallery block is not compatible with the Add to Cart + Options block in this template. Switch to the new Product Gallery block for a better experience.',
+ 'woocommerce'
+ )
+ : createInterpolateElement(
+ __(
+ 'Upgrade to the <strongText /> for more flexibility.',
+ 'woocommerce'
+ ),
+ {
+ strongText: (
+ <strong>
+ { __( `Product Gallery block`, 'woocommerce' ) }
+ </strong>
+ ),
+ }
+ );
const buttonLabel = __( 'Use the Product Gallery block', 'woocommerce' );
@@ -55,6 +45,9 @@ export const UpgradeNotice = ( {
onActionClick={ () =>
upgradeToBlockifiedProductGallery( blockClientId )
}
+ status={
+ showAddToCartWithOptionsCompatibilityNotice ? 'warning' : 'info'
+ }
>
{ notice }
</UpgradeDowngradeNotice>
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/components/upgrade-product-image-gallery/index.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/components/upgrade-product-image-gallery/index.tsx
index bdbe5b0f144..97daf22e811 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/components/upgrade-product-image-gallery/index.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/components/upgrade-product-image-gallery/index.tsx
@@ -11,7 +11,7 @@ import { findBlock } from '@woocommerce/utils';
/**
* Internal dependencies
*/
-import { replaceBlockWithProductGallery } from '../../../product-gallery/edit-utils';
+import { upgradeToBlockifiedProductGallery } from '../../../../atomic/blocks/product-elements/product-image-gallery/edit-utils';
export const UpgradeProductImageGallery = () => {
const [ productImageGalleryBlock, setProductImageGalleryBlock ] =
@@ -49,11 +49,15 @@ export const UpgradeProductImageGallery = () => {
isDismissible={ false }
actionLabel={ buttonLabel }
onActionClick={ () => {
- replaceBlockWithProductGallery(
- productImageGalleryBlock.clientId
- );
- setProductImageGalleryBlock( null );
+ if (
+ upgradeToBlockifiedProductGallery(
+ productImageGalleryBlock.clientId
+ )
+ ) {
+ setProductImageGalleryBlock( null );
+ }
} }
+ status="warning"
>
{ notice }
</UpgradeDowngradeNotice>
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-gallery/edit-utils.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/product-gallery/edit-utils.tsx
deleted file mode 100644
index 3a9e21a5a5a..00000000000
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-gallery/edit-utils.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * External dependencies
- */
-import { createBlock } from '@wordpress/blocks';
-import { dispatch } from '@wordpress/data';
-
-export const replaceBlockWithProductGallery = ( blockClientId: string ) => {
- const newBlock = createBlock( 'woocommerce/product-gallery' );
-
- dispatch( 'core/block-editor' ).replaceBlock( blockClientId, newBlock );
-
- return true;
-};
diff --git a/plugins/woocommerce/client/blocks/assets/js/editor-components/upgrade-downgrade-notice/upgrade-downgrade-notice.tsx b/plugins/woocommerce/client/blocks/assets/js/editor-components/upgrade-downgrade-notice/upgrade-downgrade-notice.tsx
index 30607ec8eb2..ca1abec1aff 100644
--- a/plugins/woocommerce/client/blocks/assets/js/editor-components/upgrade-downgrade-notice/upgrade-downgrade-notice.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/editor-components/upgrade-downgrade-notice/upgrade-downgrade-notice.tsx
@@ -15,11 +15,14 @@ export function UpgradeDowngradeNotice( {
className,
actionLabel,
onActionClick,
+ status = 'info',
...props
}: UpgradeDowngradeNoticeProps ) {
return (
<Notice
{ ...props }
+ status={ status }
+ politeness="polite"
className={ clsx(
'wc-block-editor-components-upgrade-downgrade-notice',
className
diff --git a/plugins/woocommerce/tests/e2e/tests/blocks/product-image-gallery/product-image-gallery.block_theme.spec.ts b/plugins/woocommerce/tests/e2e/tests/blocks/product-image-gallery/product-image-gallery.block_theme.spec.ts
index b0f5035df47..d26fe50470f 100644
--- a/plugins/woocommerce/tests/e2e/tests/blocks/product-image-gallery/product-image-gallery.block_theme.spec.ts
+++ b/plugins/woocommerce/tests/e2e/tests/blocks/product-image-gallery/product-image-gallery.block_theme.spec.ts
@@ -4,6 +4,11 @@
import { devices } from '@playwright/test';
import { test, expect, BLOCK_THEME_SLUG } from '@woocommerce/e2e-utils';
+/**
+ * Internal dependencies
+ */
+import AddToCartWithOptionsPage from '../add-to-cart-with-options/add-to-cart-with-options.page';
+
const blockData = {
name: 'woocommerce/product-image-gallery',
productPage: '/product/hoodie/',
@@ -126,4 +131,46 @@ test.describe( `${ blockData.name } editor`, () => {
editor.canvas.getByLabel( 'Block: Product Gallery' )
).toBeVisible();
} );
+
+ test( 'shows the Add to Cart + Options compatibility notice and can be migrated to the Product Gallery block', async ( {
+ page,
+ editor,
+ admin,
+ } ) => {
+ const pageObject = new AddToCartWithOptionsPage( {
+ page,
+ admin,
+ editor,
+ } );
+ await pageObject.updateSingleProductTemplate();
+
+ const productImageGalleryBlock = await editor.getBlockByName(
+ blockData.name
+ );
+ await editor.selectBlocks( productImageGalleryBlock );
+
+ const sidebarSettings = page.getByRole( 'region', {
+ name: 'Editor settings',
+ } );
+
+ await expect(
+ sidebarSettings.getByText(
+ 'The classic Product Image Gallery block is not compatible with the Add to Cart + Options block in this template. Switch to the new Product Gallery block for a better experience.'
+ )
+ ).toBeVisible();
+
+ await expect(
+ editor.canvas.getByLabel( 'Block: Product Gallery' )
+ ).toBeHidden();
+
+ await sidebarSettings
+ .getByRole( 'button', {
+ name: 'Use the Product Gallery block',
+ } )
+ .click();
+
+ await expect(
+ editor.canvas.getByLabel( 'Block: Product Gallery' )
+ ).toBeVisible();
+ } );
} );