Commit 919cff28940 for woocommerce
commit 919cff2894052876996809629ece47960c3c50ca
Author: SH Sajal Chowdhury <72102985+shsajalchowdhury@users.noreply.github.com>
Date: Fri May 1 21:41:46 2026 +0600
Fix: Mini Cart badge not honoring configured product count color (#64411)
* Fix Mini Cart badge not honoring configured product count color
The Interactivity API badgeBackgroundColor getter computes colors
from the DOM parent chain instead of using the configured
productCountColor block attribute, overriding the PHP-rendered
inline style after hydration.
Pass productCountColor from PHP to the Interactivity state and
use it in the badgeBackgroundColor getter when available, falling
back to getClosestColor() only when no explicit color is set.
Fixes #64176
* Add changefile(s) from automation for the following project(s): woocommerce
* Add tests for Mini Cart badge product count color
- Test that badge inline style contains configured productCountColor
- Test that badge has no background color when no color is configured
- Uses WP_HTML_Tag_Processor for HTML parsing (matches existing test patterns)
* Address CodeRabbit feedback: remove duplicate changelog and fix esc_attr placement
- Remove duplicate changelog fragment (64176-fix-mini-cart-badge-colors),
keeping only the PR-numbered fragment (64411-fix-...)
- Move esc_attr() from the color assignment to the inline style usage
so wp_interactivity_state() receives raw CSS color values instead of
HTML entities; applied consistently to both render paths
* Tighten test assertion: verify color is applied to background property
Change assertStringContainsString from checking $color anywhere in
the style to checking 'background:' . $color specifically, matching
the MiniCart $styles assignment pattern.
* Fix negative test: use 'background:' instead of loose 'background' substring
Match the positive test assertion pattern for consistency and avoid
false matches on properties like background-image or CSS variables.
---------
Co-authored-by: woocommercebot <woocommercebot@users.noreply.github.com>
diff --git a/plugins/woocommerce/changelog/64411-fix-64176-mini-cart-badge-colors b/plugins/woocommerce/changelog/64411-fix-64176-mini-cart-badge-colors
new file mode 100644
index 00000000000..043a90d65e1
--- /dev/null
+++ b/plugins/woocommerce/changelog/64411-fix-64176-mini-cart-badge-colors
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Honor the configured product count color for the Mini Cart badge on the frontend when using the Interactivity API.
\ No newline at end of file
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts b/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts
index 93fabbee27a..f73f4dcfbdc 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts
@@ -110,6 +110,7 @@ type MiniCart = {
contentsBackgroundColor: string;
badgeBackgroundColor: string | undefined;
badgeTextColor: string | undefined;
+ productCountColor: string;
};
actions: {
openDrawer: () => void;
@@ -287,6 +288,9 @@ store< MiniCart >(
get badgeBackgroundColor(): string | undefined {
if ( state.isHydrated ) {
+ if ( state.productCountColor ) {
+ return state.productCountColor;
+ }
const { ref } = getElement();
return getClosestColor( ref!, 'color' ) || '#000';
}
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php b/plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php
index 2abec4bdb5c..b883b0ac402 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php
@@ -519,8 +519,8 @@ class MiniCart extends AbstractBlock {
if ( $cart ) {
$classes_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes );
$icon_color = isset( $attributes['iconColor']['color'] ) ? esc_attr( $attributes['iconColor']['color'] ) : 'currentColor';
- $product_count_color = isset( $attributes['productCountColor']['color'] ) ? esc_attr( $attributes['productCountColor']['color'] ) : '';
- $styles = $product_count_color ? 'background:' . $product_count_color : '';
+ $product_count_color = isset( $attributes['productCountColor']['color'] ) ? $attributes['productCountColor']['color'] : '';
+ $styles = $product_count_color ? 'background:' . esc_attr( $product_count_color ) : '';
$icon = MiniCartUtils::get_svg_icon( $attributes['miniCartIcon'] ?? '', $icon_color );
$product_count_visibility = isset( $attributes['productCountVisibility'] ) ? $attributes['productCountVisibility'] : 'greater_than_zero';
$wrapper_classes = sprintf( 'wc-block-mini-cart wp-block-woocommerce-mini-cart %s', $classes_styles['classes'] );
@@ -567,6 +567,7 @@ class MiniCart extends AbstractBlock {
? sprintf( $button_aria_label_template, $state['totalItemsInCart'] )
: sprintf( $button_aria_label_template, $state['totalItemsInCart'], $state['formattedSubtotal'] );
},
+ 'productCountColor' => $product_count_color,
)
);
@@ -820,8 +821,8 @@ class MiniCart extends AbstractBlock {
$wrapper_styles = $classes_styles['styles'];
$icon_color = isset( $attributes['iconColor']['color'] ) ? esc_attr( $attributes['iconColor']['color'] ) : 'currentColor';
- $product_count_color = isset( $attributes['productCountColor']['color'] ) ? esc_attr( $attributes['productCountColor']['color'] ) : '';
- $styles = $product_count_color ? 'background:' . $product_count_color : '';
+ $product_count_color = isset( $attributes['productCountColor']['color'] ) ? $attributes['productCountColor']['color'] : '';
+ $styles = $product_count_color ? 'background:' . esc_attr( $product_count_color ) : '';
$icon = MiniCartUtils::get_svg_icon( $attributes['miniCartIcon'] ?? '', $icon_color );
$product_count_visibility = isset( $attributes['productCountVisibility'] ) ? $attributes['productCountVisibility'] : 'greater_than_zero';
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCart.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCart.php
index 58d6e178cf7..9aae16102e9 100644
--- a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCart.php
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/MiniCart.php
@@ -379,6 +379,60 @@ class MiniCart extends \WP_UnitTestCase {
$this->assertNotEmpty( $output, 'Mini-cart should render for logged-out users when coming soon mode is disabled.' );
}
+ /**
+ * Test that the product count badge includes the configured product count color in its inline style.
+ *
+ * @return void
+ */
+ public function test_badge_contains_configured_product_count_color() {
+ $color = '#ff0000';
+
+ $block = parse_blocks( '<!-- wp:woocommerce/mini-cart {"productCountColor":{"color":"' . $color . '"}} /-->' );
+ $output = render_block( $block[0] );
+
+ $processor = new \WP_HTML_Tag_Processor( $output );
+
+ $badge_found = false;
+ while ( $processor->next_tag(
+ array(
+ 'tag_name' => 'span',
+ 'class_name' => 'wc-block-mini-cart__badge',
+ )
+ ) ) {
+ $badge_found = true;
+ $style = $processor->get_attribute( 'style' );
+ $this->assertStringContainsString( 'background:' . $color, $style, 'Badge inline style should apply the configured color to the background property.' );
+ }
+
+ $this->assertTrue( $badge_found, 'Badge element should be present in the rendered output.' );
+ }
+
+ /**
+ * Test that the product count badge does not include a background color when no color is configured.
+ *
+ * @return void
+ */
+ public function test_badge_has_no_background_color_when_not_configured() {
+ $block = parse_blocks( '<!-- wp:woocommerce/mini-cart /-->' );
+ $output = render_block( $block[0] );
+
+ $processor = new \WP_HTML_Tag_Processor( $output );
+
+ $badge_found = false;
+ while ( $processor->next_tag(
+ array(
+ 'tag_name' => 'span',
+ 'class_name' => 'wc-block-mini-cart__badge',
+ )
+ ) ) {
+ $badge_found = true;
+ $style = $processor->get_attribute( 'style' );
+ $this->assertStringNotContainsString( 'background:', $style, 'Badge inline style should not contain a background color when none is configured.' );
+ }
+
+ $this->assertTrue( $badge_found, 'Badge element should be present in the rendered output.' );
+ }
+
/**
* Test that mini-cart renders for logged-out users when site-wide coming soon mode is enabled (not store pages only).
*