From 9e0c20d43e15e93aba1e3c3540b6682e0f3d23a1 Mon Sep 17 00:00:00 2001 From: Patricia Hillebrandt Date: Thu, 16 Feb 2023 11:43:37 +0100 Subject: [PATCH] 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 --- .../js/blocks/add-to-cart-form/block.json | 11 ++++ .../js/blocks/add-to-cart-form/edit.tsx | 51 +++++++++++++++ .../js/blocks/add-to-cart-form/editor.scss | 27 ++++++++ .../js/blocks/add-to-cart-form/index.tsx | 29 +++++++++ .../js/blocks/add-to-cart-form/style.scss | 7 ++ .../woocommerce-blocks/bin/webpack-entries.js | 1 + .../src/BlockTypes/AddToCartForm.php | 65 +++++++++++++++++++ .../src/BlockTypesController.php | 2 + .../specs/backend/add-to-cart-form.test.js | 61 +++++++++++++++++ 9 files changed, 254 insertions(+) create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/block.json create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/edit.tsx create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/editor.scss create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/index.tsx create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/style.scss create mode 100644 plugins/woocommerce-blocks/src/BlockTypes/AddToCartForm.php create mode 100644 plugins/woocommerce-blocks/tests/e2e/specs/backend/add-to-cart-form.test.js diff --git a/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/block.json b/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/block.json new file mode 100644 index 00000000000..7d2b45b32a2 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/block.json @@ -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" +} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/edit.tsx new file mode 100644 index 00000000000..8dd20a4c1b1 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/edit.tsx @@ -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 ( +
+ + +

+ { __( + 'Customers will see product add-to-cart options displayed here, dependent on the product type.', + 'woo-gutenberg-products-block' + ) } +

+
+ + +
+
+ ); +}; + +export default Edit; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/editor.scss b/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/editor.scss new file mode 100644 index 00000000000..a69535e2eb7 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/editor.scss @@ -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; +} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/index.tsx b/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/index.tsx new file mode 100644 index 00000000000..7d192b782f4 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/index.tsx @@ -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: ( + + ), + }, + attributes: { + ...metadata.attributes, + }, + edit, + save() { + return null; + }, +} ); diff --git a/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/style.scss b/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/style.scss new file mode 100644 index 00000000000..ba006d7de88 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/add-to-cart-form/style.scss @@ -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; +} diff --git a/plugins/woocommerce-blocks/bin/webpack-entries.js b/plugins/woocommerce-blocks/bin/webpack-entries.js index 46e0e773b92..3b03f77d997 100644 --- a/plugins/woocommerce-blocks/bin/webpack-entries.js +++ b/plugins/woocommerce-blocks/bin/webpack-entries.js @@ -13,6 +13,7 @@ const glob = require( 'glob' ); // property. const blocks = { 'active-filters': {}, + 'add-to-cart-form': {}, 'all-products': { customDir: 'products/all-products', }, diff --git a/plugins/woocommerce-blocks/src/BlockTypes/AddToCartForm.php b/plugins/woocommerce-blocks/src/BlockTypes/AddToCartForm.php new file mode 100644 index 00000000000..bf45693b1bf --- /dev/null +++ b/plugins/woocommerce-blocks/src/BlockTypes/AddToCartForm.php @@ -0,0 +1,65 @@ +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( + '
%4$s
', + 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; + } +} diff --git a/plugins/woocommerce-blocks/src/BlockTypesController.php b/plugins/woocommerce-blocks/src/BlockTypesController.php index 653b766daf2..3aceae34083 100644 --- a/plugins/woocommerce-blocks/src/BlockTypesController.php +++ b/plugins/woocommerce-blocks/src/BlockTypesController.php @@ -165,6 +165,7 @@ final class BlockTypesController { $block_types = [ 'ActiveFilters', + 'AddToCartForm', 'AllProducts', 'AllReviews', 'AttributeFilter', @@ -252,6 +253,7 @@ final class BlockTypesController { $block_types = array_diff( $block_types, [ + 'AddToCartForm', 'Breadcrumbs', 'CatalogSorting', 'ClassicTemplate', diff --git a/plugins/woocommerce-blocks/tests/e2e/specs/backend/add-to-cart-form.test.js b/plugins/woocommerce-blocks/tests/e2e/specs/backend/add-to-cart-form.test.js new file mode 100644 index 00000000000..978114b9348 --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e/specs/backend/add-to-cart-form.test.js @@ -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 ); + } ); + } ); +} );