woocommerce/plugins/woocommerce-blocks/packages/checkout/blocks-registry
Mike Jolley eb196226d8 WIP: Add Inner blocks to order summary (https://github.com/woocommerce/woocommerce-blocks/pull/6065)
* Sub/Total/Fee inner blocks

* Row blocks within the inner block

* Update icons

* Resolve stying issues

* Remove old block

* Pin totals row

* Locking logic update

* Heading inner block

* Refactor where inner blocks are defined

* Add todos

* Todo for Consider deprecating OrderMetaSlotFill and DiscountSlotFill in favour of inner block areas.

* Improve frontend registration of components using new entrypoint

* Experiment- external block context

* Revert "Experiment- external block context"

This reverts commit 4b75668ec7eb62f065c6a488cd942a666e26204f.

* Duplicate inner blocks to avoid conflicts with context

* Remove todo

* Rename block dir

* Some test fixes

* Fix import

* fix import

* linting

* Remove unused attributes

* Optional classname

* fix coupons import

* fix shipping mocks

* Styling

* Fix selectors in e2e tests

* Add back the wc-block-components-totals-wrapper class that was used for each segment in the totals Order summary

Because, removing them was:
-  a breaking change for the old structure
- was making it harder to target the inner blocks. Before the class was used to target each segment
- it was making the wc-block-components-totals-item behave as a child or parent depending on the inner block, inconsitency

* Reuse the TotalsWrapper component for C& C blocks inner blocks

This component was removed in this PR, but  we wrap components in the Cart and Checkout sidebar in a TotalsWrapper. This will ensure consistent spacing and borders are applied to items in the sidebar.

Co-authored-by: Nadir Seghir <nadir.seghir@gmail.com>
Co-authored-by: Raluca Stan <ralucastn@gmail.com>
2022-04-01 15:45:18 +02:00
..
test Update checkout block registration API to consume Block Metadata (https://github.com/woocommerce/woocommerce-blocks/pull/4684) 2021-09-07 17:01:14 +01:00
README.md Update some Cart and Checkout extensibility docs to include the Mini Cart block (https://github.com/woocommerce/woocommerce-blocks/pull/5815) 2022-02-21 16:29:29 +01:00
get-registered-blocks.ts Add Checkout Package and Checkout i2 Documentation (https://github.com/woocommerce/woocommerce-blocks/pull/4892) 2021-10-12 15:23:52 +01:00
index.ts Refactor Checkout Inner Block Registration and Render frontend forced blocks (https://github.com/woocommerce/woocommerce-blocks/pull/4671) 2021-09-03 14:25:09 +01:00
inserter.png Add Checkout Package and Checkout i2 Documentation (https://github.com/woocommerce/woocommerce-blocks/pull/4892) 2021-10-12 15:23:52 +01:00
register-checkout-block.ts Update checkout block registration API to consume Block Metadata (https://github.com/woocommerce/woocommerce-blocks/pull/4684) 2021-09-07 17:01:14 +01:00
registered-blocks.ts Update checkout block registration API to consume Block Metadata (https://github.com/woocommerce/woocommerce-blocks/pull/4684) 2021-09-07 17:01:14 +01:00
types.ts WIP: Add Inner blocks to order summary (https://github.com/woocommerce/woocommerce-blocks/pull/6065) 2022-04-01 15:45:18 +02:00
utils.ts Update checkout block registration API to consume Block Metadata (https://github.com/woocommerce/woocommerce-blocks/pull/4684) 2021-09-07 17:01:14 +01:00

README.md

Checkout - Blocks Registry

This directory contains the Checkout Blocks Registry. This provides functions to register new Inner Blocks that can be inserted automatically, or optionally, within the Mini Cart, Cart and Checkout blocks in certain areas.

Registered Inner Blocks can either be forced within the layout of the Cart/Checkout Block, or they can just be made available to merchants so they can be inserted manually. Inner Blocks registered in this way can also define a component to render on the frontend in place of the Block.

Table of Contents

How Inner Blocks Work

The Checkout Block has several areas in which inner blocks can be registered and added. Once registered, blocks can be inserted by merchants:

Inner Block Inserter

If a block is forced, merchants won't see the option to insert the block, they will just see the block inserted by default, and they won't be able to remove it from the layout.

Inner Block Areas

Blocks can be registered within several different areas or parent blocks. Valid values at time of writing include:

Parent Block/Area Description
woocommerce/checkout-totals-block The right side of the checkout containing order totals.
woocommerce/checkout-fields-block The left side of the checkout containing checkout form steps.
woocommerce/checkout-contact-information-block Within the contact information form step.
woocommerce/checkout-shipping-address-block Within the shipping address form step.
woocommerce/checkout-billing-address-block Within the billing address form step.
woocommerce/checkout-shipping-methods-block Within the shipping methods form step.
woocommerce/checkout-payment-methods-block Within the payment methods form step.

See the innerBlockAreas typedef for the most up to date list of available areas.

Registering a Block

To register a checkout block, first, register your Block Type with WordPress using https://developer.wordpress.org/block-editor/reference-guides/block-api/block-registration/. We recommend using the blocks.json method to avoid repetition.

When registering your block, you should also define the parent property to include a list of areas where your block will be available. For example:

{
	"name": "woocommerce/checkout-actions-block",
	"title": "Actions",
	"description": "Allow customers to place their order.",
	"category": "woocommerce",
	"parent": [ "woocommerce/checkout-fields-block" ]
	// ...snip
}

Registering a Forced Block

If you want your block to appear within the layout of the Checkout without merchant intervention, you can implement locking as follows:

{
	"name": "woocommerce/checkout-actions-block",
	"title": "Actions",
	"description": "Allow customers to place their order.",
	"category": "woocommerce",
	"parent": [ "woocommerce/checkout-fields-block" ],
	"attributes": {
		"lock": {
			"type": "object",
			"default": {
				"remove": true,
				"move": true
			}
		}
	}
	// ...snip
}

In the above example, the inner block would be inserted automatically, and would not be movable or removable by the merchant.

Passing attributes to your frontend block

For your block to dynamically render on the frontend and have access to its own attributes, both the block name and the list of block attributes need to be passed via HTML data- attributes.

  • To render the block on the frontend, you need a data-block-name attribute on the HTML with your block name namespace/block-name.
  • To access your attributes on frontend, you need to save them as data-* attributes on the HTML.

Blocks whose namespace is woocommerce or woocommerce-checkout will have this applied to them automatically, but you can also add this behaviour to your own namespace or individual blocks.

To add this behavior to your namespace, you can use the __experimental_woocommerce_blocks_add_data_attributes_to_namespace filter:

add_filter(
	'__experimental_woocommerce_blocks_add_data_attributes_to_namespace',
	function ( $allowed_namespaces ) {
		$allowed_namespaces[] = 'namespace';
		return $allowed_namespaces;
	},
	10,
	1
);

To add just a single block, you can use __experimental_woocommerce_blocks_add_data_attributes_to_block filter:

add_filter(
	'__experimental_woocommerce_blocks_add_data_attributes_to_block',
	function ( $allowed_blocks ) {
		$allowed_blocks[] = 'namespace/block-name';
		return $allowed_blocks;
	},
	10,
	1
);

Registering a Block Component

After registering your block, you need to define which component will replace your block on the frontend of the store. To do this, use the registerCheckoutBlock function from the checkout blocks registry.

registerCheckoutBlock( options )

This function registers a block and it's corresponding component with WooCommerce. The register function expects a JavaScript object with options specific to the block you are registering.

Usage

// Aliased import
import { registerCheckoutBlock } from '@woocommerce/blocks-checkout';

// Global import
// const { registerCheckoutBlock } = wc.blocksCheckout;

const options = {
	metadata: {
		name: 'namespace/block-name',
		parent: [ 'woocommerce/checkout-totals-block' ],
	},
	component: () => <div>A Function Component</div>,
};

registerCheckoutBlock( options );

Options

The following options are available:

metadata (object, required)

This is a your blocks metadata (from blocks.json). It needs to define at least a name (block name), and parent (the areas on checkout) to be valid.

component (function, required)

This is a React component that should replace the Block on the frontend. It will be fed any attributes from the Block and have access to any public context providers under the Checkout context.

You should provide either a React Component or a React.lazy() component if you wish to lazy load for performance reasons.

getRegisteredBlocks( blockName )

Returns an array of registered block objects available within a specific parent block/area.

Usage

// Aliased import
import { getRegisteredBlocks } from '@woocommerce/blocks-checkout';

// Global import
// const { getRegisteredBlocks } = wc.blocksCheckout;

const registeredBlocks = getRegisteredBlocks(
	'woocommerce/checkout-totals-block'
);

hasInnerBlocks( blockName )

Check if a block/area supports inner block registration.

Usage

// Aliased import
import { hasInnerBlocks } from '@woocommerce/blocks-checkout';

// Global import
// const { hasInnerBlocks } = wc.blocksCheckout;

const isValid = hasInnerBlocks( 'woocommerce/checkout-totals-block' ); // true

We're hiring! Come work with us!

🐞 Found a mistake, or have a suggestion? Leave feedback about this document here.