From 2af90f301c17d30e637636e660dff815761d98da Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 21 Sep 2021 16:41:09 +0100 Subject: [PATCH] Add/empty and fillted cart wrapper (https://github.com/woocommerce/woocommerce-blocks/pull/4803) * Update area/types * Add empty and filled block wrappers * Add missing useBlockProps * Add templates and inner block structure --- .../cart-checkout/cart-i2/attributes.js | 5 +- .../js/blocks/cart-checkout/cart-i2/edit.tsx | 185 +++++++++--------- .../blocks/cart-checkout/cart-i2/editor.scss | 33 ---- .../blocks/cart-checkout/cart-i2/frontend.js | 2 +- .../js/blocks/cart-checkout/cart-i2/index.js | 22 +-- .../inner-blocks/cart-items-block/block.json | 2 +- .../inner-blocks/cart-totals-block/block.json | 2 +- .../inner-blocks/empty-cart-block/block.json | 26 +++ .../inner-blocks/empty-cart-block/edit.tsx | 38 ++++ .../inner-blocks/empty-cart-block/index.tsx | 20 ++ .../inner-blocks/filled-cart-block/block.json | 26 +++ .../inner-blocks/filled-cart-block/edit.tsx | 44 +++++ .../filled-cart-block/editor.scss | 23 +++ .../inner-blocks/filled-cart-block/index.tsx | 20 ++ .../cart-i2/inner-blocks/index.tsx | 4 +- .../js/blocks/cart-checkout/cart-i2/types.ts | 13 ++ .../checkout/blocks-registry/types.ts | 3 +- 17 files changed, 316 insertions(+), 152 deletions(-) create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/block.json create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/edit.tsx create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/index.tsx create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/block.json create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/edit.tsx create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/editor.scss create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/index.tsx create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/types.ts diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/attributes.js b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/attributes.js index dadbb2d57e1..1163619a20e 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/attributes.js +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/attributes.js @@ -3,7 +3,8 @@ */ import { getSetting } from '@woocommerce/settings'; -const blockAttributes = { +export const blockName = 'woocommerce/cart-i2'; +export const blockAttributes = { isPreview: { type: 'boolean', default: false, @@ -26,5 +27,3 @@ const blockAttributes = { default: true, }, }; - -export default blockAttributes; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/edit.tsx index ac39ebf6f78..8fc7c1e5570 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/edit.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/edit.tsx @@ -5,11 +5,13 @@ import classnames from 'classnames'; import { __ } from '@wordpress/i18n'; import { CartCheckoutFeedbackPrompt } from '@woocommerce/editor-components/feedback-prompt'; -import { InnerBlocks, InspectorControls } from '@wordpress/block-editor'; +import { + InnerBlocks, + useBlockProps, + InspectorControls, +} from '@wordpress/block-editor'; import { PanelBody, ToggleControl, Notice } from '@wordpress/components'; -import PropTypes from 'prop-types'; import { CartCheckoutCompatibilityNotice } from '@woocommerce/editor-components/compatibility-notices'; -import ViewSwitcher from '@woocommerce/editor-components/view-switcher'; import { CART_PAGE_ID } from '@woocommerce/block-settings'; import BlockErrorBoundary from '@woocommerce/base-components/block-error-boundary'; import { @@ -20,15 +22,30 @@ import { import { createInterpolateElement } from '@wordpress/element'; import { getAdminLink, getSetting } from '@woocommerce/settings'; import { previewCart } from '@woocommerce/resource-previews'; -import { SidebarLayout } from '@woocommerce/base-components/sidebar-layout'; /** * Internal dependencies */ import './editor.scss'; -import { Columns } from './columns'; +import { addClassToBody } from './hacks'; +import type { Attributes } from './types'; -const BlockSettings = ( { attributes, setAttributes } ) => { +// This is adds a class to body to signal if the selected block is locked +addClassToBody(); + +// Array of allowed block names. +const ALLOWED_BLOCKS: string[] = [ + 'woocommerce/filled-cart-block', + 'woocommerce/empty-cart-block', +]; + +const BlockSettings = ( { + attributes, + setAttributes, +}: { + attributes: Attributes; + setAttributes: ( attributes: Record< string, unknown > ) => undefined; +} ): JSX.Element => { const { isShippingCalculatorEnabled, showRateAfterTaxName } = attributes; const { currentPostId } = useEditorContext(); return ( @@ -113,42 +130,43 @@ const BlockSettings = ( { attributes, setAttributes } ) => { ); }; -const ALLOWED_BLOCKS: string[] = [ - 'woocommerce/cart-items-block', - 'woocommerce/cart-totals-block', -]; /** * Component to handle edit mode of "Cart Block". - * - * Note: We need to always render `` in the editor. Otherwise, - * if the user saves the page without having triggered the 'Empty Cart' - * view, inner blocks would not be saved and they wouldn't be visible - * in the frontend. - * - * @param {Object} props Incoming props for the component. - * @param {string} props.className CSS class used. - * @param {Object} props.attributes Attributes available. - * @param {function(any):any} props.setAttributes Setter for attributes. */ -const CartEditor = ( { className, attributes, setAttributes } ) => { - const cartClassName = classnames( 'wc-block-cart', { +export const Edit = ( { + className, + attributes, + setAttributes, +}: { + className: string; + attributes: Attributes; + setAttributes: ( attributes: Record< string, unknown > ) => undefined; +} ): JSX.Element => { + const cartClassName = classnames( { 'has-dark-controls': attributes.hasDarkControls, } ); const defaultInnerBlocksTemplate = [ [ - 'woocommerce/cart-items-block', - {}, - [ [ 'woocommerce/cart-line-items-block', {}, [] ] ], - ], - [ - 'woocommerce/cart-totals-block', + 'woocommerce/filled-cart-block', {}, [ - [ 'woocommerce/cart-order-summary-block', {}, [] ], - [ 'woocommerce/cart-express-payment-block', {}, [] ], - [ 'woocommerce/proceed-to-checkout-block', {}, [] ], + [ + 'woocommerce/cart-items-block', + {}, + [ [ 'woocommerce/cart-line-items-block', {}, [] ] ], + ], + [ + 'woocommerce/cart-totals-block', + {}, + [ + [ 'woocommerce/cart-order-summary-block', {}, [] ], + [ 'woocommerce/cart-express-payment-block', {}, [] ], + [ 'woocommerce/proceed-to-checkout-block', {}, [] ], + ], + ], ], ], + [ 'woocommerce/empty-cart-block', {}, [] ], ]; return (
{ 'is-editor-preview': attributes.isPreview, } ) } > - ( - - { currentView === 'full' && ( - <> - - - - - - - - - - - - ) } - + + text={ __( + 'There was an error whilst rendering the cart block. If this problem continues, try re-creating the block.', + 'woo-gutenberg-products-block' + ) } + showErrorMessage={ true } + errorMessagePrefix={ __( + 'Error message:', + 'woo-gutenberg-products-block' + ) } + > + + + +
+ +
+
+
+
); }; -CartEditor.propTypes = { - className: PropTypes.string, +export const Save = (): JSX.Element => { + return ( +
+ +
+ ); }; - -export default CartEditor; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/editor.scss b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/editor.scss index 45d3d6b1fc6..d39e5532fbb 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/editor.scss +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/editor.scss @@ -2,39 +2,6 @@ margin: 0; } -.wp-block-woocommerce-cart.is-editor-preview { - max-height: 1000px; - overflow: hidden; -} - -.wp-block-woocommerce-cart-i2 { - .wc-block-components-sidebar-layout { - display: block; - } - .block-editor-block-list__layout { - display: flex; - flex-flow: row wrap; - align-items: flex-start; - - .wc-block-cart__additional_fields { - padding: 0; - } - } - .wc-block-components-main, - .wc-block-components-sidebar, - .block-editor-block-list__layout { - > :first-child { - margin-top: 0; - } - } - .wp-block-woocommerce-cart-totals-block, - .wp-block-woocommerce-cart-items-block { - .block-editor-block-list__layout { - display: block; - } - } -} - body.wc-lock-selected-block--move { .block-editor-block-mover__move-button-container, .block-editor-block-mover { diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/frontend.js b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/frontend.js index 954c87ca87a..b255032afe5 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/frontend.js +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/frontend.js @@ -21,7 +21,7 @@ import { * Internal dependencies */ import Block from './block.js'; -import blockAttributes from './attributes'; +import { blockAttributes } from './attributes'; const reloadPage = () => void window.location.reload( true ); /** diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/index.js b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/index.js index 3ae97a7f1e2..02247247770 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/index.js +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/index.js @@ -2,17 +2,17 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; -import { InnerBlocks } from '@wordpress/block-editor'; import { Icon, cart } from '@woocommerce/icons'; -import classnames from 'classnames'; import { registerFeaturePluginBlockType } from '@woocommerce/block-settings'; + /** * Internal dependencies */ -import edit from './edit'; +import { Edit, Save } from './edit'; import './style.scss'; -import blockAttributes from './attributes'; +import { blockName, blockAttributes } from './attributes'; import './inner-blocks'; + /** * Register and run the Cart block. */ @@ -36,16 +36,8 @@ const settings = { }, }, attributes: blockAttributes, - edit, - - // Save the props to post content. - save( { attributes } ) { - return ( -
- -
- ); - }, + edit: Edit, + save: Save, }; -registerFeaturePluginBlockType( 'woocommerce/cart-i2', settings ); +registerFeaturePluginBlockType( blockName, settings ); diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/cart-items-block/block.json b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/cart-items-block/block.json index 92cab95529d..df58ae99a1b 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/cart-items-block/block.json +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/cart-items-block/block.json @@ -20,7 +20,7 @@ } } }, - "parent": [ "woocommerce/cart-i2" ], + "parent": [ "woocommerce/filled-cart-block" ], "textdomain": "woo-gutenberg-products-block", "apiVersion": 2 } diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/cart-totals-block/block.json b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/cart-totals-block/block.json index b048fefcfbf..d8d9a2438bc 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/cart-totals-block/block.json +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/cart-totals-block/block.json @@ -27,7 +27,7 @@ } } }, - "parent": [ "woocommerce/cart-i2" ], + "parent": [ "woocommerce/filled-cart-block" ], "textdomain": "woo-gutenberg-products-block", "apiVersion": 2 } diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/block.json b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/block.json new file mode 100644 index 00000000000..0119c8fe7f2 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/block.json @@ -0,0 +1,26 @@ +{ + "name": "woocommerce/empty-cart-block", + "version": "1.0.0", + "title": "Empty Cart", + "description": "Contains blocks that are displayed when the cart is empty.", + "category": "woocommerce", + "supports": { + "align": false, + "html": false, + "multiple": false, + "reusable": false, + "inserter": false + }, + "attributes": { + "lock": { + "type": "object", + "default": { + "remove": true, + "move": true + } + } + }, + "parent": [ "woocommerce/cart-i2" ], + "textdomain": "woo-gutenberg-products-block", + "apiVersion": 2 +} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/edit.tsx new file mode 100644 index 00000000000..eb5b48ac217 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/edit.tsx @@ -0,0 +1,38 @@ +/** + * External dependencies + */ +import { useBlockProps, InnerBlocks } from '@wordpress/block-editor'; +import { innerBlockAreas } from '@woocommerce/blocks-checkout'; + +/** + * Internal dependencies + */ +import { useForcedLayout } from '../../use-forced-layout'; +import { getAllowedBlocks } from '../../editor-utils'; + +export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => { + const blockProps = useBlockProps(); + const allowedBlocks = getAllowedBlocks( innerBlockAreas.EMPTY_CART ); + + useForcedLayout( { + clientId, + template: allowedBlocks, + } ); + return ( +
+ This is the empty cart block. + +
+ ); +}; + +export const Save = (): JSX.Element => { + return ( +
+ +
+ ); +}; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/index.tsx b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/index.tsx new file mode 100644 index 00000000000..0d734d6cd03 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/empty-cart-block/index.tsx @@ -0,0 +1,20 @@ +/** + * External dependencies + */ +import { Icon, removeCart } from '@woocommerce/icons'; +import { registerFeaturePluginBlockType } from '@woocommerce/block-settings'; + +/** + * Internal dependencies + */ +import { Edit, Save } from './edit'; +import metadata from './block.json'; + +registerFeaturePluginBlockType( metadata, { + icon: { + src: , + foreground: '#874FB9', + }, + edit: Edit, + save: Save, +} ); diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/block.json b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/block.json new file mode 100644 index 00000000000..3eeea67ac5d --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/block.json @@ -0,0 +1,26 @@ +{ + "name": "woocommerce/filled-cart-block", + "version": "1.0.0", + "title": "Filled Cart", + "description": "Contains blocks that are displayed when the cart contains products.", + "category": "woocommerce", + "supports": { + "align": false, + "html": false, + "multiple": false, + "reusable": false, + "inserter": false + }, + "attributes": { + "lock": { + "type": "object", + "default": { + "remove": true, + "move": true + } + } + }, + "parent": [ "woocommerce/cart-i2" ], + "textdomain": "woo-gutenberg-products-block", + "apiVersion": 2 +} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/edit.tsx new file mode 100644 index 00000000000..bf0f44f33a5 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/edit.tsx @@ -0,0 +1,44 @@ +/** + * External dependencies + */ +import { useBlockProps, InnerBlocks } from '@wordpress/block-editor'; +import { innerBlockAreas } from '@woocommerce/blocks-checkout'; +import { SidebarLayout } from '@woocommerce/base-components/sidebar-layout'; + +/** + * Internal dependencies + */ +import { useForcedLayout } from '../../use-forced-layout'; +import { getAllowedBlocks } from '../../editor-utils'; +import { Columns } from './../../columns'; +import './editor.scss'; + +export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => { + const blockProps = useBlockProps(); + const allowedBlocks = getAllowedBlocks( innerBlockAreas.FILLED_CART ); + + useForcedLayout( { + clientId, + template: allowedBlocks, + } ); + return ( +
+ + + + + +
+ ); +}; + +export const Save = (): JSX.Element => { + return ( +
+ +
+ ); +}; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/editor.scss b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/editor.scss new file mode 100644 index 00000000000..486c7e30e9c --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/editor.scss @@ -0,0 +1,23 @@ +.wp-block-woocommerce-filled-cart-block { + .wc-block-components-sidebar-layout { + display: block; + } + .block-editor-block-list__layout { + display: flex; + flex-flow: row wrap; + align-items: flex-start; + } + .wc-block-components-main, + .wc-block-components-sidebar, + .block-editor-block-list__layout { + > :first-child { + margin-top: 0; + } + } + .wp-block-woocommerce-cart-totals-block, + .wp-block-woocommerce-cart-items-block { + .block-editor-block-list__layout { + display: block; + } + } +} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/index.tsx b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/index.tsx new file mode 100644 index 00000000000..704af1b38aa --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/filled-cart-block/index.tsx @@ -0,0 +1,20 @@ +/** + * External dependencies + */ +import { Icon, cart } from '@woocommerce/icons'; +import { registerFeaturePluginBlockType } from '@woocommerce/block-settings'; + +/** + * Internal dependencies + */ +import { Edit, Save } from './edit'; +import metadata from './block.json'; + +registerFeaturePluginBlockType( metadata, { + icon: { + src: , + foreground: '#874FB9', + }, + edit: Edit, + save: Save, +} ); diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/index.tsx b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/index.tsx index 56f735f86f1..7b8e15bf183 100644 --- a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/index.tsx +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/inner-blocks/index.tsx @@ -1,9 +1,11 @@ /** * Internal dependencies */ +import './filled-cart-block'; import './cart-items-block'; -import './cart-totals-block'; import './cart-line-items-block'; +import './cart-totals-block'; import './cart-order-summary-block'; import './cart-express-payment-block'; import './proceed-to-checkout-block'; +import './empty-cart-block'; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/types.ts b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/types.ts new file mode 100644 index 00000000000..bfed3662013 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/cart-checkout/cart-i2/types.ts @@ -0,0 +1,13 @@ +export type InnerBlockTemplate = [ + string, + Record< string, unknown >, + InnerBlockTemplate[] | undefined +]; + +export interface Attributes { + isPreview: boolean; + isShippingCalculatorEnabled: boolean; + hasDarkControls: boolean; + showRateAfterTaxName: boolean; + checkoutPageId: number; +} diff --git a/plugins/woocommerce-blocks/packages/checkout/blocks-registry/types.ts b/plugins/woocommerce-blocks/packages/checkout/blocks-registry/types.ts index e27e6e7fd2f..87cba030a78 100644 --- a/plugins/woocommerce-blocks/packages/checkout/blocks-registry/types.ts +++ b/plugins/woocommerce-blocks/packages/checkout/blocks-registry/types.ts @@ -13,7 +13,8 @@ export enum innerBlockAreas { BILLING_ADDRESS = 'woocommerce/checkout-billing-address-block', SHIPPING_METHODS = 'woocommerce/checkout-shipping-methods-block', PAYMENT_METHODS = 'woocommerce/checkout-payment-methods-block', - CART = 'woocommerce/cart-i2', + EMPTY_CART = 'woocommerce/empty-cart-block', + FILLED_CART = 'woocommerce/filled-cart-block', CART_ITEMS = 'woocommerce/cart-items-block', CART_TOTALS = 'woocommerce/cart-totals-block', }