Commit f5828efba37 for woocommerce
commit f5828efba3715f8aff3b6503a91dcb77918fd420
Author: Tung Du <dinhtungdu@gmail.com>
Date: Wed Oct 14 11:36:52 2026 +0700
Fix Product Button margins adding to parent block spacing (#69583)
* Fix Product Button margins adding to parent block spacing
* Add changelog entries for Product Button spacing
diff --git a/plugins/woocommerce/changelog/fix-67314-product-button-margin b/plugins/woocommerce/changelog/fix-67314-product-button-margin
new file mode 100644
index 00000000000..cac9c60cc2a
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-67314-product-button-margin
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Respect Product Button margins without adding the parent block spacing.
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.json b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.json
index 3cf188450ac..5854d599e67 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.json
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.json
@@ -55,12 +55,16 @@
"spacing": {
"margin": true,
"padding": true,
- "__experimentalSkipSerialization": true
+ "__experimentalSkipSerialization": [ "padding" ]
},
"email": true
},
"selectors": {
- "root": ".wp-block-woocommerce-product-button .wc-block-components-product-button__button"
+ "root": ".wp-block-woocommerce-product-button .wc-block-components-product-button__button",
+ "spacing": {
+ "margin": ".wp-block-woocommerce-product-button",
+ "padding": ".wp-block-woocommerce-product-button .wc-block-components-product-button__button"
+ }
},
"ancestor": [
"woocommerce/all-products",
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.tsx
index be3fb7d3804..bd323c9eb70 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/block.tsx
@@ -286,6 +286,21 @@ const AddToCartButtonPlaceholder = ( {
export const Block = ( props: BlockAttributes ): JSX.Element => {
const { className, textAlign, blockClientId, collection } = props;
const styleProps = useStyleProps( props );
+ const {
+ margin,
+ marginTop,
+ marginRight,
+ marginBottom,
+ marginLeft,
+ ...buttonStyle
+ } = styleProps.style;
+ const blockMarginStyle = {
+ margin,
+ marginTop,
+ marginRight,
+ marginBottom,
+ marginLeft,
+ };
const { parentClassName } = useInnerBlockLayoutContext();
const { product, isLoading } = useProductDataContext( {
product: props.product,
@@ -307,11 +322,12 @@ export const Block = ( props: BlockAttributes ): JSX.Element => {
[ `align-${ textAlign }` ]: textAlign,
}
) }
+ style={ props.isAdmin ? undefined : blockMarginStyle }
>
{ isLoading ? (
<LoadingAddToCartButton
className={ styleProps.className }
- style={ styleProps.style }
+ style={ buttonStyle }
/>
) : (
<>
@@ -330,7 +346,7 @@ export const Block = ( props: BlockAttributes ): JSX.Element => {
( product && product?.id ? (
<AddToCartButton
product={ product }
- style={ styleProps.style }
+ style={ buttonStyle }
className={ styleProps.className }
isAdmin={ props.isAdmin }
isDescendantOfAddToCartWithOptions={
@@ -343,7 +359,7 @@ export const Block = ( props: BlockAttributes ): JSX.Element => {
/>
) : (
<AddToCartButtonPlaceholder
- style={ styleProps.style }
+ style={ buttonStyle }
className={ styleProps.className }
isLoading={ isLoading ?? false }
blockClientId={ blockClientId }
diff --git a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/test/block.test.tsx b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/test/block.test.tsx
index b5cc2f01cf8..62d94907a7a 100644
--- a/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/test/block.test.tsx
+++ b/plugins/woocommerce/client/blocks/assets/js/blocks/product-elements-blocks/button/test/block.test.tsx
@@ -6,11 +6,12 @@ import {
useStoreAddToCart,
useStoreEvents,
} from '@woocommerce/base-context/hooks';
+import { useStyleProps } from '@woocommerce/base-hooks';
/**
* Internal dependencies
*/
-import { AddToCartButton } from '../block';
+import { AddToCartButton, Block } from '../block';
import type { AddToCartButtonAttributes } from '../types';
jest.mock( '@woocommerce/base-context/hooks', () => ( {
@@ -18,7 +19,18 @@ jest.mock( '@woocommerce/base-context/hooks', () => ( {
useStoreEvents: jest.fn(),
} ) );
-jest.mock( '@woocommerce/base-hooks', () => ( {} ) );
+jest.mock( '@woocommerce/base-hooks', () => ( {
+ useStyleProps: jest.fn(),
+} ) );
+
+jest.mock( '@woocommerce/shared-context', () => ( {
+ useInnerBlockLayoutContext: () => ( {} ),
+ useProductDataContext: () => ( {} ),
+} ) );
+
+jest.mock( '../../../../shared/stores/product-type-template-state', () => ( {
+ useProductTypeSelector: () => ( {} ),
+} ) );
jest.mock( '@woocommerce/block-settings', () => ( {
CART_URL: '/cart/',
@@ -85,3 +97,24 @@ describe( 'AddToCartButton', () => {
expect( link ).toHaveAttribute( 'rel', 'nofollow' );
} );
} );
+
+describe( 'Product Button spacing', () => {
+ it.each( [ true, false ] )(
+ 'keeps padding on the button and leaves editor margin to block supports (isAdmin=%s)',
+ ( isAdmin ) => {
+ ( useStyleProps as jest.Mock ).mockReturnValue( {
+ className: '',
+ style: { marginTop: '12px', paddingTop: '10px' },
+ } );
+
+ const { container } = render( <Block isAdmin={ isAdmin } /> );
+ const wrapper = container.firstElementChild as HTMLElement;
+ const button = screen.getByRole( 'button' );
+
+ expect( wrapper.style.marginTop ).toBe( isAdmin ? '' : '12px' );
+ expect( wrapper.style.paddingTop ).toBe( '' );
+ expect( button.style.marginTop ).toBe( '' );
+ expect( button ).toHaveStyle( { paddingTop: '10px' } );
+ }
+ );
+} );
diff --git a/plugins/woocommerce/client/blocks/changelog/fix-67314-product-button-margin b/plugins/woocommerce/client/blocks/changelog/fix-67314-product-button-margin
new file mode 100644
index 00000000000..cac9c60cc2a
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/changelog/fix-67314-product-button-margin
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Respect Product Button margins without adding the parent block spacing.
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php b/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php
index 2858eaf7218..b3aeaa06aae 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php
@@ -99,7 +99,7 @@ class ProductButton extends AbstractBlock {
$ajax_add_to_cart_enabled = get_option( 'woocommerce_enable_ajax_add_to_cart' ) === 'yes';
$is_ajax_button = ( ( $ajax_add_to_cart_enabled && $product->supports( 'ajax_add_to_cart' ) ) || $is_descendant_of_add_to_cart_form ) && $is_product_purchasable && ! $cart_redirect_after_add;
$html_element = $is_ajax_button || ( $is_descendant_of_add_to_cart_form && ! $product->is_type( ProductType::EXTERNAL ) ) ? 'button' : 'a';
- $styles_and_classes = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes, array(), array( 'extra_classes' ) );
+ $styles_and_classes = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes, array(), array( 'extra_classes', 'margin' ) );
$classname = StyleAttributesUtils::get_classes_by_attributes( $attributes, array( 'extra_classes' ) );
$custom_width_classes = isset( $attributes['width'] ) ? 'has-custom-width wp-block-button__width-' . $attributes['width'] : '';
$custom_align_classes = isset( $attributes['textAlign'] ) ? 'align-' . $attributes['textAlign'] : '';