Commit 5c99c26b44b for woocommerce

commit 5c99c26b44b9d26c76f4cad6b9104306ea56ff88
Author: verofasulo <98944206+verofasulo@users.noreply.github.com>
Date:   Thu May 14 17:36:57 2026 +0200

    Add per-tab empty states to the experimental products app (#64913)

    Add per-tab empty states to the experimental products app list

diff --git a/packages/js/experimental-products-app/changelog/add-products-app-empty-states b/packages/js/experimental-products-app/changelog/add-products-app-empty-states
new file mode 100644
index 00000000000..7a5da5b9113
--- /dev/null
+++ b/packages/js/experimental-products-app/changelog/add-products-app-empty-states
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add per-tab empty states to the experimental products app product list (All, Published, Draft, Pending review, Trash) using the design-system EmptyState component.
diff --git a/packages/js/experimental-products-app/src/product-list/empty-state/icon.tsx b/packages/js/experimental-products-app/src/product-list/empty-state/icon.tsx
new file mode 100644
index 00000000000..9e6e67f9089
--- /dev/null
+++ b/packages/js/experimental-products-app/src/product-list/empty-state/icon.tsx
@@ -0,0 +1,36 @@
+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+
+export function ProductListEmptyStateIcon() {
+	return (
+		<svg
+			width="48"
+			height="48"
+			viewBox="0 0 48 48"
+			fill="none"
+			xmlns="http://www.w3.org/2000/svg"
+			role="img"
+			aria-label={ __( 'No products', 'woocommerce' ) }
+		>
+			<g style={ { mixBlendMode: 'multiply' } }>
+				<g clipPath="url(#products-empty-state-clip)">
+					<path
+						d="M31.9489 8.0315H25.014V4.69394H23.6479C22.7194 4.69394 22.3285 4.22477 22.3285 3.35313C22.3285 2.48149 22.7194 2.01232 23.6479 2.01232C24.1122 2.01232 26.0292 1.99676 26.0292 1.99676V0L23.2059 0.0155649C21.2001 0.0155649 20.0361 1.36304 20.0361 3.35313C20.0361 5.34322 21.1379 6.62176 23.0393 6.69514V8.0315H16.0489C16.0489 8.0315 8.03223 11.7804 8.03223 12.0117H40.0189C40.0189 11.7804 31.9467 8.0315 31.9467 8.0315H31.9489Z"
+						fill="#F0F0F0"
+					/>
+					<path
+						d="M48 18.0133C48 18.0133 40.1144 10.4243 38.8838 9.47037C37.8242 8.64988 36.5292 8.01172 34.0103 8.01172H31.9489C31.6335 12.1987 28.266 15.494 23.9989 15.494C19.7318 15.494 16.3643 12.1987 16.0489 8.01172H13.9875C11.4686 8.01172 10.1735 8.64766 9.11398 9.47037C7.8856 10.4243 0 18.0133 0 18.0133L2.72553 26.0181H9.95807L9.95141 48.0025H38.0508L38.0442 26.0181H45.2767L48.0022 18.0133H48Z"
+						fill="#E0E0E0"
+					/>
+				</g>
+			</g>
+			<defs>
+				<clipPath id="products-empty-state-clip">
+					<rect width="48" height="48" fill="white" />
+				</clipPath>
+			</defs>
+		</svg>
+	);
+}
diff --git a/packages/js/experimental-products-app/src/product-list/empty-state/index.tsx b/packages/js/experimental-products-app/src/product-list/empty-state/index.tsx
new file mode 100644
index 00000000000..baa3982e32c
--- /dev/null
+++ b/packages/js/experimental-products-app/src/product-list/empty-state/index.tsx
@@ -0,0 +1,80 @@
+/**
+ * External dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { EmptyState } from '@wordpress/ui';
+
+/**
+ * Internal dependencies
+ */
+import type { StatusTab } from '../constants';
+import { ProductListEmptyStateIcon } from './icon';
+
+type EmptyStateCopy = {
+	title: string;
+	description: string;
+};
+
+function getEmptyStateCopy( tab: StatusTab ): EmptyStateCopy {
+	switch ( tab ) {
+		case 'publish':
+			return {
+				title: __( 'No products published yet', 'woocommerce' ),
+				description: __(
+					'Check your drafts or add a new product to start selling.',
+					'woocommerce'
+				),
+			};
+		case 'draft':
+			return {
+				title: __( 'No draft products yet', 'woocommerce' ),
+				description: __(
+					'Any products you save as drafts will be listed here.',
+					'woocommerce'
+				),
+			};
+		case 'pending':
+			return {
+				title: __( 'No products awaiting review', 'woocommerce' ),
+				description: __(
+					'Products submitted for review will appear here.',
+					'woocommerce'
+				),
+			};
+		case 'trash':
+			return {
+				title: __( 'No products in trash', 'woocommerce' ),
+				description: __(
+					'Deleted products will move here, where you can restore or remove them permanently.',
+					'woocommerce'
+				),
+			};
+		case 'all':
+		default:
+			return {
+				title: __( 'No products yet', 'woocommerce' ),
+				description: __(
+					'All your products will appear here.',
+					'woocommerce'
+				),
+			};
+	}
+}
+
+type ProductListEmptyStateProps = {
+	tab: StatusTab;
+};
+
+export function ProductListEmptyState( { tab }: ProductListEmptyStateProps ) {
+	const { title, description } = getEmptyStateCopy( tab );
+
+	return (
+		<EmptyState.Root className="woocommerce-product-list__empty-state">
+			<EmptyState.Visual>
+				<ProductListEmptyStateIcon />
+			</EmptyState.Visual>
+			<EmptyState.Title>{ title }</EmptyState.Title>
+			<EmptyState.Description>{ description }</EmptyState.Description>
+		</EmptyState.Root>
+	);
+}
diff --git a/packages/js/experimental-products-app/src/product-list/index.tsx b/packages/js/experimental-products-app/src/product-list/index.tsx
index afb659e200c..c32a90e1f14 100644
--- a/packages/js/experimental-products-app/src/product-list/index.tsx
+++ b/packages/js/experimental-products-app/src/product-list/index.tsx
@@ -45,6 +45,7 @@ import {
 	isProductEditorAccessible,
 } from './utils';
 import { useProductActions } from '../dataviews-actions';
+import { ProductListEmptyState } from './empty-state';

 const { Menu } = unlock( componentsPrivateApis );
 const { usePostActions } = unlock( editorPrivateApis );
@@ -334,6 +335,7 @@ export default function ProductList( {
 				selection={ selection }
 				defaultLayouts={ DEFAULT_LAYOUTS }
 				isItemClickable={ isProductEditorAccessible }
+				empty={ <ProductListEmptyState tab={ selectedTab } /> }
 				renderItemLink={ ( { item, ...props } ) => (
 					<a
 						{ ...props }