Commit cb780991a4e for woocommerce

commit cb780991a4e00a5bc870940ca05435ce2ebc009b
Author: Francesco <frosso@users.noreply.github.com>
Date:   Fri Aug 28 22:58:30 2026 +0200

    fix: type of Store API item_data hidden flag (#68159)

diff --git a/plugins/woocommerce/changelog/fix-store-api-item-data-hidden-type b/plugins/woocommerce/changelog/fix-store-api-item-data-hidden-type
new file mode 100644
index 00000000000..bfe2e8e8268
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-store-api-item-data-hidden-type
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Correct the public TypeScript type for the Store API item_data `hidden` flag, which arrives as a string rather than a boolean.
diff --git a/plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/test/index.js b/plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/test/index.js
index 18a8a7745e1..26cfc9d16da 100644
--- a/plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/test/index.js
+++ b/plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/test/index.js
@@ -54,7 +54,7 @@ describe( 'ProductDetails', () => {

 	test( 'should not render hidden details', () => {
 		const details = [
-			{ name: 'Lorem', value: 'Ipsum', hidden: true },
+			{ name: 'Lorem', value: 'Ipsum', hidden: '1' },
 			{ name: 'LOREM', value: 'Ipsum', display: 'IPSUM' },
 			{ name: 'LOREM 2', value: 'Ipsum2', display: 'IPSUM 2' },
 		];
@@ -83,10 +83,24 @@ describe( 'ProductDetails', () => {
 		expect( screen.getByText( 'IPSUM 2' ) ).toBeInTheDocument();
 	} );

+	// The Store API runs every item_data value through wp_kses_post(), which
+	// string-coerces, so an extension's boolean arrives as '1' or ''.
+	test( 'should treat the string hidden flags the Store API actually sends', () => {
+		const details = [
+			{ name: 'Hidden', value: 'Ipsum', hidden: '1' },
+			{ name: 'Visible', value: 'Ipsum2', hidden: '' },
+		];
+
+		render( <ProductDetails details={ details } /> );
+
+		expect( screen.queryByText( 'Hidden:' ) ).not.toBeInTheDocument();
+		expect( screen.getByText( 'Visible:' ) ).toBeInTheDocument();
+	} );
+
 	test( 'should not render anything if all details are hidden', () => {
 		const details = [
-			{ name: 'Lorem', value: 'Ipsum', hidden: true },
-			{ name: 'LOREM', value: 'Ipsum', display: 'IPSUM', hidden: true },
+			{ name: 'Lorem', value: 'Ipsum', hidden: '1' },
+			{ name: 'LOREM', value: 'Ipsum', display: 'IPSUM', hidden: '1' },
 		];

 		const { container } = render( <ProductDetails details={ details } /> );
diff --git a/plugins/woocommerce/client/blocks/packages/public-api/types/type-defs/product-response.ts b/plugins/woocommerce/client/blocks/packages/public-api/types/type-defs/product-response.ts
index 55dbe6f2530..b6562c9d871 100644
--- a/plugins/woocommerce/client/blocks/packages/public-api/types/type-defs/product-response.ts
+++ b/plugins/woocommerce/client/blocks/packages/public-api/types/type-defs/product-response.ts
@@ -13,7 +13,13 @@ export interface ProductResponseItemPrices extends CurrencyResponse {
 export interface ProductResponseItemBaseData {
 	value: string;
 	display?: string;
-	hidden?: boolean;
+	/**
+	 * Truthy marks the entry hidden. Always a string: the Store API runs every
+	 * `item_data` value through `wp_kses_post()`, which string-coerces, so a
+	 * boolean set by an extension arrives as `"1"` or `""`. Test it for
+	 * truthiness — comparing against `true` or `1` can never match.
+	 */
+	hidden?: string;
 	className?: string;
 }