Commit 75696966639 for woocommerce
commit 756969666392a90fd2802ae86ab3d0efd70f5ffb
Author: verofasulo <98944206+verofasulo@users.noreply.github.com>
Date: Wed May 13 10:44:56 2026 +0200
Add Brands filter to the experimental products app product list (#64826)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Luigi Teschio <gigitux@gmail.com>
diff --git a/packages/js/experimental-products-app/changelog/add-products-app-brand-filter b/packages/js/experimental-products-app/changelog/add-products-app-brand-filter
new file mode 100644
index 00000000000..6548bf6495b
--- /dev/null
+++ b/packages/js/experimental-products-app/changelog/add-products-app-brand-filter
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add a Brands filter to the experimental products app product list.
diff --git a/packages/js/experimental-products-app/src/fields/brands/field.tsx b/packages/js/experimental-products-app/src/fields/brands/field.tsx
index 62af1c3efbc..ea6482ee4df 100644
--- a/packages/js/experimental-products-app/src/fields/brands/field.tsx
+++ b/packages/js/experimental-products-app/src/fields/brands/field.tsx
@@ -1,6 +1,8 @@
/**
* External dependencies
*/
+import { resolveSelect } from '@wordpress/data';
+import { store as coreStore } from '@wordpress/core-data';
import { __ } from '@wordpress/i18n';
import { decodeEntities } from '@wordpress/html-entities';
import type { Field } from '@wordpress/dataviews';
@@ -14,7 +16,9 @@ const fieldDefinition = {
type: 'array',
label: __( 'Brands', 'woocommerce' ),
enableSorting: false,
- filterBy: false,
+ filterBy: {
+ operators: [ 'isAny' ],
+ },
} satisfies Partial< Field< ProductEntityRecord > >;
export const fieldExtensions: Partial< Field< ProductEntityRecord > > = {
@@ -33,4 +37,15 @@ export const fieldExtensions: Partial< Field< ProductEntityRecord > > = {
return <span>{ names.join( ', ' ) }</span>;
},
+ getElements: async () => {
+ const records = ( await resolveSelect( coreStore ).getEntityRecords(
+ 'taxonomy',
+ 'product_brand',
+ { per_page: -1 }
+ ) ) as Array< { id: number; name: string } > | null;
+ return ( records ?? [] ).map( ( { id, name } ) => ( {
+ value: id.toString(),
+ label: decodeEntities( name ),
+ } ) );
+ },
};
diff --git a/packages/js/experimental-products-app/src/product-list/query.test.ts b/packages/js/experimental-products-app/src/product-list/query.test.ts
index f4934d475bf..a840e641542 100644
--- a/packages/js/experimental-products-app/src/product-list/query.test.ts
+++ b/packages/js/experimental-products-app/src/product-list/query.test.ts
@@ -158,4 +158,19 @@ describe( 'buildProductListQuery', () => {
expect( query.stock_status ).toBe( 'onbackorder' );
} );
+
+ it( 'maps the brands isAny filter to the brand query param', () => {
+ const query = buildProductListQuery( {
+ ...baseView,
+ filters: [
+ {
+ field: 'brands',
+ operator: 'isAny',
+ value: [ '8', 9 ],
+ },
+ ],
+ } as View );
+
+ expect( query.brand ).toEqual( '8,9' );
+ } );
} );
diff --git a/packages/js/experimental-products-app/src/product-list/query.ts b/packages/js/experimental-products-app/src/product-list/query.ts
index e267d4712e0..2447ae5ceed 100644
--- a/packages/js/experimental-products-app/src/product-list/query.ts
+++ b/packages/js/experimental-products-app/src/product-list/query.ts
@@ -18,6 +18,7 @@ export type ProductListQuery = Omit< ProductQuery, 'status' > & {
exclude_category?: number[];
min_stock_quantity?: string;
max_stock_quantity?: string;
+ brand?: string;
};
const SUPPORTED_STATUS_FILTER_FIELDS = [ 'status', 'product_status' ];
@@ -111,6 +112,16 @@ function applyCategoryFilter( query: ProductListQuery, filter: Filter ) {
query.category = values.join( ',' );
}
+function applyBrandFilter( query: ProductListQuery, filter: Filter ) {
+ const values = getNumericValues( filter.value );
+
+ if ( values.length === 0 ) {
+ return;
+ }
+
+ query.brand = values.join( ',' );
+}
+
function applyStockFilter( query: ProductListQuery, filter: Filter ) {
const [ stockStatus ] = getStringValues( filter.value );
@@ -173,6 +184,9 @@ export function buildProductListQuery( view: View ): ProductListQuery {
case 'categories':
applyCategoryFilter( query, filter );
break;
+ case 'brands':
+ applyBrandFilter( query, filter );
+ break;
case 'stock':
applyStockFilter( query, filter );
break;