Add more Inspector controls for Product(Add to cart) button (https://github.com/woocommerce/woocommerce-blocks/pull/8781)

* Add Fill & Outline styles to Product button

This commit adds the Fill & Outline styles to the Product button block.
You can see new Styles section in Inspector Controls where you will be able to change between Fill & Outline styles.

* Add width setting to product button

The button block now has a width selector, which allows the user to
set the button to 25%, 50%, 75%, or 100% of the parent container.
By default, a button's width is determined by the size of its content.

You can find this setting in the button block's sidebar.

* Enable all typography controls

Now following typography controls are also available:
- Font Family
- Appearance
- Line height
- Letter spacing
- Decoration
- Letter case

* Fix width settings not working

* Fix align doesn't work with Width settings

* Fix width setting not working in Single product block

* Fix - Default button is shorter on the frontend

In Editor default and outlined button has the same height. Outlined button in the frontend as well. But default button on the frontend is shorter (smaller padding)

More info: https://github.com/woocommerce/woocommerce-blocks/pull/8781#issuecomment-1477527049

* Fix - background color not matching when GB is enabled

* Fix - 100% width button exceeds the container

Fix following issues:
- "Select Options" or "View products" for variable and grouped products don't respect the container max width
- Also, for small width (25%) they are wider

More info: https://github.com/woocommerce/woocommerce-blocks/pull/8781#issuecomment-1477527049

* Fix: Width setting not working in All Products block

This commit fixes the width setting not working in the All Products block.

* Keep other classes along with Width setting classes

`block.attributes.className` should be kept along with the width setting classes.
```
className: classnames( block.attributes.className, {
	[ `has-custom-width wp-block-button__width-${ block.attributes?.width }` ]:
		block.attributes?.width,
} )
```

* Translate styles label in block configuration
This commit is contained in:
Manish Menaria 2023-03-24 12:38:43 +05:30 committed by GitHub
parent 8b57aa35cb
commit 1416642cd2
10 changed files with 193 additions and 7 deletions

View File

@ -16,6 +16,9 @@ export const blockAttributes: BlockAttributes = {
type: 'string',
default: '',
},
width: {
type: 'number',
},
};
export default blockAttributes;

View File

@ -15,3 +15,5 @@ export const BLOCK_DESCRIPTION: string = __(
'Display a call to action button which either adds the product to the cart, or links to the product page.',
'woo-gutenberg-products-block'
);
export const BLOCK_NAME = 'woocommerce/product-button';

View File

@ -1,11 +1,19 @@
/**
* External dependencies
*/
import { Disabled } from '@wordpress/components';
import classnames from 'classnames';
import {
Disabled,
Button,
ButtonGroup,
PanelBody,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import {
AlignmentToolbar,
BlockControls,
useBlockProps,
InspectorControls,
} from '@wordpress/block-editor';
import type { BlockEditProps } from '@wordpress/blocks';
import { useEffect } from '@wordpress/element';
@ -17,6 +25,52 @@ import { ProductQueryContext as Context } from '@woocommerce/blocks/product-quer
import Block from './block';
import { BlockAttributes } from './types';
function WidthPanel( {
selectedWidth,
setAttributes,
}: {
selectedWidth: number | undefined;
setAttributes: ( attributes: BlockAttributes ) => void;
} ) {
function handleChange( newWidth: number ) {
// Check if we are toggling the width off
const width = selectedWidth === newWidth ? undefined : newWidth;
// Update attributes.
setAttributes( { width } );
}
return (
<PanelBody
title={ __( 'Width settings', 'woo-gutenberg-products-block' ) }
>
<ButtonGroup
aria-label={ __(
'Button width',
'woo-gutenberg-products-block'
) }
>
{ [ 25, 50, 75, 100 ].map( ( widthValue ) => {
return (
<Button
key={ widthValue }
isSmall
variant={
widthValue === selectedWidth
? 'primary'
: undefined
}
onClick={ () => handleChange( widthValue ) }
>
{ widthValue }%
</Button>
);
} ) }
</ButtonGroup>
</PanelBody>
);
}
const Edit = ( {
attributes,
setAttributes,
@ -26,6 +80,7 @@ const Edit = ( {
} ): JSX.Element => {
const blockProps = useBlockProps();
const isDescendentOfQueryLoop = Number.isFinite( context?.queryId );
const { width } = attributes;
useEffect(
() => setAttributes( { isDescendentOfQueryLoop } ),
@ -43,9 +98,21 @@ const Edit = ( {
/>
) }
</BlockControls>
<InspectorControls>
<WidthPanel
selectedWidth={ width }
setAttributes={ setAttributes }
/>
</InspectorControls>
<div { ...blockProps }>
<Disabled>
<Block { ...{ ...attributes, ...context } } />
<Block
{ ...{ ...attributes, ...context } }
className={ classnames( attributes.className, {
[ `has-custom-width wp-block-button__width-${ width }` ]:
width,
} ) }
/>
</Disabled>
</div>
</>

View File

@ -3,6 +3,7 @@
*/
import { registerBlockType } from '@wordpress/blocks';
import type { BlockConfiguration } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
@ -11,10 +12,12 @@ import { supports } from './supports';
import attributes from './attributes';
import sharedConfig from '../shared/config';
import edit from './edit';
import save from './save';
import {
BLOCK_TITLE as title,
BLOCK_ICON as icon,
BLOCK_DESCRIPTION as description,
BLOCK_NAME,
} from './constants';
const blockConfig: BlockConfiguration = {
@ -32,6 +35,18 @@ const blockConfig: BlockConfiguration = {
attributes,
supports,
edit,
save,
styles: [
{
name: 'fill',
label: __( 'Fill', 'woo-gutenberg-products-block' ),
isDefault: true,
},
{
name: 'outline',
label: __( 'Outline', 'woo-gutenberg-products-block' ),
},
],
};
registerBlockType( 'woocommerce/product-button', { ...blockConfig } );
registerBlockType( BLOCK_NAME, { ...blockConfig } );

View File

@ -0,0 +1,33 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import classnames from 'classnames';
/**
* Internal dependencies
*/
import { BlockAttributes } from './types';
type Props = {
attributes: BlockAttributes;
};
const Save = ( { attributes }: Props ): JSX.Element | null => {
if ( attributes.isDescendentOfQueryLoop ) {
return null;
}
return (
<div
{ ...useBlockProps.save( {
className: classnames( 'is-loading', attributes.className, {
[ `has-custom-width wp-block-button__width-${ attributes.width }` ]:
attributes.width,
} ),
} ) }
/>
);
};
export default Save;

View File

@ -40,3 +40,35 @@
}
}
// Style: Fill & Outline
.wp-block-button.is-style-outline {
.wp-block-button__link {
border: 2px solid currentColor;
&:not(.has-text-color) {
color: currentColor;
}
&:not(.has-background) {
background-color: transparent;
background-image: none;
}
}
}
// Width setting
.wp-block-button {
&.has-custom-width {
.wp-block-button__link {
box-sizing: border-box;
}
}
@for $i from 1 through 4 {
&.wp-block-button__width-#{$i * 25} {
.wp-block-button__link {
width: $i * 25%; // 25%, 50%, 75%, 100%
}
}
}
}

View File

@ -26,8 +26,16 @@ export const supports = {
} ),
typography: {
fontSize: true,
lineHeight: true,
__experimentalFontWeight: true,
__experimentalSkipSerialization: true,
__experimentalFontFamily: true,
__experimentalFontStyle: true,
__experimentalTextTransform: true,
__experimentalTextDecoration: true,
__experimentalLetterSpacing: true,
__experimentalDefaultControls: {
fontSize: true,
},
},
__experimentalSelector:
'.wp-block-button.wc-block-components-product-button .wc-block-components-product-button__button',

View File

@ -10,6 +10,7 @@ export interface BlockAttributes {
className?: string | undefined;
textAlign?: string | undefined;
isDescendentOfQueryLoop?: boolean | undefined;
width?: number | undefined;
}
export interface AddToCartButtonPlaceholderAttributes {

View File

@ -1,3 +1,13 @@
/**
* External dependencies
*/
import classnames from 'classnames';
/**
* Internal dependencies
*/
import { BLOCK_NAME as PRODUCT_BUTTON_BLOCK_NAME } from '../../atomic/blocks/product-elements/button/constants';
/**
* The default layout built from the default template.
*/
@ -29,6 +39,17 @@ export const getProductLayoutConfig = ( innerBlocks ) => {
block.innerBlocks.length > 0
? getProductLayoutConfig( block.innerBlocks )
: [],
/**
* Add custom width class to Add to cart button,
* This is needed to support "Width Setting" controls available in
* "woocommerce/product-button" block.
*/
...( block.name === PRODUCT_BUTTON_BLOCK_NAME && {
className: classnames( block.attributes.className, {
[ `has-custom-width wp-block-button__width-${ block.attributes?.width }` ]:
block.attributes?.width,
} ),
} ),
},
];
} );

View File

@ -89,13 +89,16 @@ 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 && ! $cart_redirect_after_add && $product->supports( 'ajax_add_to_cart' ) && $product->is_purchasable() && $product->is_in_stock();
$html_element = $is_ajax_button ? 'button' : 'a';
$styles_and_classes = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes, array( 'border_radius', 'font_size', 'font_weight', 'margin', 'padding', 'text_color' ) );
$styles_and_classes = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes );
$text_align_styles_and_classes = StyleAttributesUtils::get_text_align_class_and_style( $attributes );
$classname = isset( $attributes['className'] ) ? $attributes['className'] : '';
$custom_width_classes = isset( $attributes['width'] ) ? 'has-custom-width wp-block-button__width-' . $attributes['width'] : '';
$html_classes = implode(
' ',
array_filter(
array(
'wp-block-button__link',
'wp-element-button',
'wc-block-components-product-button__button',
$product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
$is_ajax_button ? 'ajax_add_to_cart' : '',
@ -137,10 +140,11 @@ class ProductButton extends AbstractBlock {
return apply_filters(
'woocommerce_loop_add_to_cart_link',
sprintf(
'<div class="wp-block-button wc-block-components-product-button wc-block-grid__product-add-to-cart %1$s">
<%2$s href="%3$s" class="%4$s" style="%5$s" %6$s>%7$s</%2$s>
'<div class="wp-block-button wc-block-components-product-button %1$s %2$s">
<%3$s href="%4$s" class="%5$s" style="%6$s" %7$s>%8$s</%3$s>
</div>',
esc_attr( $text_align_styles_and_classes['class'] ?? '' ),
esc_attr( $classname . ' ' . $custom_width_classes ),
$html_element,
esc_url( $product->add_to_cart_url() ),
isset( $args['class'] ) ? esc_attr( $args['class'] ) : '',