Create the Add to Cart Form Block (https://github.com/woocommerce/woocommerce-blocks/pull/8284)
* Add the initial basis for the Add to Cart button * Trigger the single product add to cart action for each product type. * Rename the block from add-to-cart-button to add-to-cart-form * Update to use the cart icon. * Implement the skeleton for the editor preview. * Update styles and add Notice for the display in the Editor. * Update CSS. * Add base tests for the new Add to Cart Form component. * Update the button CSS. * Update styles for the cart form. * update td style. * Update divs and CSS. * Use conventional input instead of the experimental InputControl * Implement the new design and copy provided for the editor. * Make the notice compatible with dark themes. * Some additional CSS tweaks * adjust the padding for the input * Update the icon for the block to match the core icon button
This commit is contained in:
parent
3b04dbb01f
commit
9e0c20d43e
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "woocommerce/add-to-cart-form",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"title": "Add to Cart form",
|
||||||
|
"description": "Display a button so the customer can add a product to their cart. Options will also be displayed depending on product type. e.g. quantity, variation.",
|
||||||
|
"category": "woocommerce",
|
||||||
|
"keywords": [ "WooCommerce" ],
|
||||||
|
"textdomain": "woo-gutenberg-products-block",
|
||||||
|
"apiVersion": 2,
|
||||||
|
"$schema": "https://schemas.wp.org/trunk/block.json"
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { useBlockProps } from '@wordpress/block-editor';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { Button, Disabled, Notice } from '@wordpress/components';
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import './editor.scss';
|
||||||
|
export interface Attributes {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Edit = () => {
|
||||||
|
const blockProps = useBlockProps( {
|
||||||
|
className: 'woocommerce wc-block-add-to-cart-form',
|
||||||
|
} );
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div { ...blockProps }>
|
||||||
|
<Disabled>
|
||||||
|
<Notice
|
||||||
|
className={ 'wc-block-add-to-cart-form__notice' }
|
||||||
|
status={ 'warning' }
|
||||||
|
isDismissible={ false }
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
{ __(
|
||||||
|
'Customers will see product add-to-cart options displayed here, dependent on the product type.',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
</p>
|
||||||
|
</Notice>
|
||||||
|
<input
|
||||||
|
type={ 'number' }
|
||||||
|
value={ '1' }
|
||||||
|
className={ 'wc-block-add-to-cart-form__quantity' }
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
variant={ 'primary' }
|
||||||
|
className={ 'wc-block-add-to-cart-form__button' }
|
||||||
|
>
|
||||||
|
{ __( 'Add to cart', 'woo-gutenberg-products-block' ) }
|
||||||
|
</Button>
|
||||||
|
</Disabled>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Edit;
|
|
@ -0,0 +1,27 @@
|
||||||
|
.wc-block-add-to-cart-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-add-to-cart-form__notice {
|
||||||
|
margin: 10px 0;
|
||||||
|
color: $black;
|
||||||
|
max-width: 60%;
|
||||||
|
}
|
||||||
|
input.wc-block-add-to-cart-form__quantity {
|
||||||
|
width: 35px;
|
||||||
|
float: left;
|
||||||
|
padding: 10px 6px 10px 12px;
|
||||||
|
margin-right: 10px;
|
||||||
|
height: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"]::-webkit-inner-spin-button {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-add-to-cart-form__button {
|
||||||
|
float: left;
|
||||||
|
padding: 20px 30px;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { registerBlockType } from '@wordpress/blocks';
|
||||||
|
import { Icon, button } from '@wordpress/icons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import metadata from './block.json';
|
||||||
|
import edit from './edit';
|
||||||
|
|
||||||
|
registerBlockType( metadata, {
|
||||||
|
icon: {
|
||||||
|
src: (
|
||||||
|
<Icon
|
||||||
|
icon={ button }
|
||||||
|
className="wc-block-editor-components-block-icon"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
attributes: {
|
||||||
|
...metadata.attributes,
|
||||||
|
},
|
||||||
|
edit,
|
||||||
|
save() {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
} );
|
|
@ -0,0 +1,7 @@
|
||||||
|
.woocommerce.wc-block-add-to-cart-form {
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.woocommerce .wc-block-add-to-cart-form .product .summary {
|
||||||
|
float: left;
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ const glob = require( 'glob' );
|
||||||
// property.
|
// property.
|
||||||
const blocks = {
|
const blocks = {
|
||||||
'active-filters': {},
|
'active-filters': {},
|
||||||
|
'add-to-cart-form': {},
|
||||||
'all-products': {
|
'all-products': {
|
||||||
customDir: 'products/all-products',
|
customDir: 'products/all-products',
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Automattic\WooCommerce\Blocks\BlockTypes;
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CatalogSorting class.
|
||||||
|
*/
|
||||||
|
class AddToCartForm extends AbstractBlock {
|
||||||
|
/**
|
||||||
|
* Block name.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $block_name = 'add-to-cart-form';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the block.
|
||||||
|
*
|
||||||
|
* @param array $attributes Block attributes.
|
||||||
|
* @param string $content Block content.
|
||||||
|
* @param WP_Block $block Block instance.
|
||||||
|
*
|
||||||
|
* @return string | void Rendered block output.
|
||||||
|
*/
|
||||||
|
protected function render( $attributes, $content, $block ) {
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
while ( have_posts() ) {
|
||||||
|
the_post();
|
||||||
|
global $product;
|
||||||
|
/**
|
||||||
|
* Trigger the single product add to cart action for each product type.
|
||||||
|
*/
|
||||||
|
do_action( 'woocommerce_' . $product->get_type() . '_add_to_cart' );
|
||||||
|
}
|
||||||
|
|
||||||
|
$product = ob_get_clean();
|
||||||
|
|
||||||
|
if ( ! $product ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$classname = $attributes['className'] ?? '';
|
||||||
|
$classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes );
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'<div class="woocommerce wc-block-add-to-cart-form %1$s %2$s" style="%3$s"><div class="product type-product"><div class="summary entry-summary">%4$s</div></div></div>',
|
||||||
|
esc_attr( $classes_and_styles['classes'] ),
|
||||||
|
esc_attr( $classname ),
|
||||||
|
esc_attr( $classes_and_styles['styles'] ),
|
||||||
|
$product
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the frontend script handle for this block type.
|
||||||
|
*
|
||||||
|
* @param string $key Data to get, or default to everything.
|
||||||
|
*/
|
||||||
|
protected function get_block_type_script( $key = null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -165,6 +165,7 @@ final class BlockTypesController {
|
||||||
|
|
||||||
$block_types = [
|
$block_types = [
|
||||||
'ActiveFilters',
|
'ActiveFilters',
|
||||||
|
'AddToCartForm',
|
||||||
'AllProducts',
|
'AllProducts',
|
||||||
'AllReviews',
|
'AllReviews',
|
||||||
'AttributeFilter',
|
'AttributeFilter',
|
||||||
|
@ -252,6 +253,7 @@ final class BlockTypesController {
|
||||||
$block_types = array_diff(
|
$block_types = array_diff(
|
||||||
$block_types,
|
$block_types,
|
||||||
[
|
[
|
||||||
|
'AddToCartForm',
|
||||||
'Breadcrumbs',
|
'Breadcrumbs',
|
||||||
'CatalogSorting',
|
'CatalogSorting',
|
||||||
'ClassicTemplate',
|
'ClassicTemplate',
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
canvas,
|
||||||
|
createNewPost,
|
||||||
|
insertBlock,
|
||||||
|
switchUserToAdmin,
|
||||||
|
} from '@wordpress/e2e-test-utils';
|
||||||
|
import { searchForBlock } from '@wordpress/e2e-test-utils/build/inserter';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
filterCurrentBlocks,
|
||||||
|
goToSiteEditor,
|
||||||
|
useTheme,
|
||||||
|
waitForCanvas,
|
||||||
|
} from '../../utils.js';
|
||||||
|
|
||||||
|
const block = {
|
||||||
|
name: 'Add to Cart form',
|
||||||
|
slug: 'woocommerce/add-to-cart-form',
|
||||||
|
class: '.wc-block-add-to-cart-form',
|
||||||
|
};
|
||||||
|
|
||||||
|
describe( `${ block.name } Block`, () => {
|
||||||
|
it( 'in can not be inserted in a post', async () => {
|
||||||
|
await switchUserToAdmin();
|
||||||
|
await createNewPost( {
|
||||||
|
postType: 'post',
|
||||||
|
title: block.name,
|
||||||
|
} );
|
||||||
|
await searchForBlock( block.name );
|
||||||
|
expect( page ).toMatch( 'No results found.' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
describe( 'in FSE editor', () => {
|
||||||
|
useTheme( 'emptytheme' );
|
||||||
|
|
||||||
|
beforeEach( async () => {
|
||||||
|
await goToSiteEditor();
|
||||||
|
await waitForCanvas();
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'can be inserted in FSE area', async () => {
|
||||||
|
await insertBlock( block.name );
|
||||||
|
await expect( canvas() ).toMatchElement( block.class );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'can be inserted more than once', async () => {
|
||||||
|
await insertBlock( block.name );
|
||||||
|
await insertBlock( block.name );
|
||||||
|
const foo = await filterCurrentBlocks(
|
||||||
|
( b ) => b.name === block.slug
|
||||||
|
);
|
||||||
|
expect( foo ).toHaveLength( 2 );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
Loading…
Reference in New Issue