Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hydrate Cart Order Summary Coupon Form inner block using BHE #54

Merged
merged 14 commits into from
Aug 26, 2022

Conversation

cbravobernal
Copy link
Collaborator

@cbravobernal cbravobernal commented Aug 5, 2022

As mentioned on the tracking issue #20

As for hydrating the Cart block or other blocks that include inner blocks, the plan becomes a bit more complex. It would be a good idea to try to first hydrate a single inner block of the Cart block (like the aforementioned Summary Coupon Form). Then, we can progressively expand the set of hydrated inner blocks until all of them are hydrated using the technique from BHE, including the Cart itself.

This PR tries to hydrate the Cart Order Summary Coupon Form inner block by using our Block Hydration experiments.

Fixes #66

  • Register the block using BHE registerBlockType().
  • Remove the current block registration implementation.
  • Prevent the hydration from the parent block.
  • Code cleaning and refactor
  • Prevent attribute duplication

@github-actions
Copy link
Contributor

github-actions bot commented Aug 5, 2022

Size Change: +1.03 kB (0%)

Total Size: 873 kB

Filename Size Change
build/active-filters-frontend.js 7.33 kB +12 B (0%)
build/all-products-frontend.js 18.6 kB +552 B (+3%)
build/all-products.js 33.8 kB -2 B (0%)
build/attribute-filter-frontend.js 21.9 kB +6 B (0%)
build/cart-blocks/cart-accepted-payment-methods-frontend.js 1.16 kB +2 B (0%)
build/cart-blocks/cart-express-payment-frontend.js 4.52 kB -573 B (-11%) 👏
build/cart-blocks/cart-line-items--mini-cart-contents-block/products-table-frontend.js 5.26 kB -5 B (0%)
build/cart-blocks/cart-line-items-frontend.js 431 B +1 B (0%)
build/cart-blocks/cart-order-summary-frontend.js 1.1 kB +1 B (0%)
build/cart-blocks/cart-totals-frontend.js 322 B +1 B (0%)
build/cart-blocks/empty-cart-frontend.js 346 B +1 B (0%)
build/cart-blocks/filled-cart-frontend.js 781 B -1 B (0%)
build/cart-blocks/order-summary-coupon-form-frontend.js 0 B -2.65 kB (removed) 🏆
build/cart-blocks/order-summary-discount-frontend.js 1.68 kB -467 B (-22%) 🎉
build/cart-blocks/order-summary-fee-frontend.js 273 B +1 B (0%)
build/cart-blocks/order-summary-heading-frontend.js 453 B -2 B (0%)
build/cart-blocks/order-summary-shipping--checkout-blocks/order-summary-shipping-frontend.js 5.27 kB -1.12 kB (-17%) 👏
build/cart-blocks/order-summary-shipping-frontend.js 428 B +5 B (+1%)
build/cart-blocks/order-summary-subtotal-frontend.js 274 B +1 B (0%)
build/cart-blocks/order-summary-taxes-frontend.js 433 B +2 B (0%)
build/cart-blocks/proceed-to-checkout-frontend.js 988 B -164 B (-14%) 👏
build/cart-frontend.js 50.7 kB +3.6 kB (+8%) 🔍
build/cart.js 43.4 kB +176 B (0%)
build/checkout-blocks/actions-frontend.js 1.41 kB +2 B (0%)
build/checkout-blocks/billing-address--checkout-blocks/shipping-address-frontend.js 4.13 kB +10 B (0%)
build/checkout-blocks/contact-information-frontend.js 2.84 kB +6 B (0%)
build/checkout-blocks/express-payment-frontend.js 5.39 kB +7 B (0%)
build/checkout-blocks/fields-frontend.js 345 B +1 B (0%)
build/checkout-blocks/order-note-frontend.js 1.08 kB -1 B (0%)
build/checkout-blocks/order-summary-cart-items-frontend.js 3.66 kB -1 B (0%)
build/checkout-blocks/order-summary-coupon-form-frontend.js 2.79 kB -8 B (0%)
build/checkout-blocks/order-summary-discount-frontend.js 2.27 kB +7 B (0%)
build/checkout-blocks/order-summary-fee-frontend.js 276 B +1 B (0%)
build/checkout-blocks/order-summary-frontend.js 1.1 kB +1 B (0%)
build/checkout-blocks/order-summary-shipping-frontend.js 1.97 kB +1.37 kB (+228%) 🆘
build/checkout-blocks/order-summary-subtotal-frontend.js 274 B +1 B (0%)
build/checkout-blocks/order-summary-taxes-frontend.js 433 B +3 B (+1%)
build/checkout-blocks/payment-frontend.js 7.71 kB +16 B (0%)
build/checkout-blocks/shipping-address-frontend.js 1.03 kB -1 B (0%)
build/checkout-blocks/shipping-methods-frontend.js 4.78 kB +4 B (0%)
build/checkout-blocks/terms-frontend.js 1.22 kB +7 B (+1%)
build/checkout-blocks/totals-frontend.js 326 B +1 B (0%)
build/checkout-frontend.js 49.3 kB +82 B (0%)
build/checkout.js 44.6 kB -6 B (0%)
build/featured-category.js 13.2 kB -2 B (0%)
build/featured-product.js 13.5 kB -2 B (0%)
build/legacy-template.js 2.8 kB -1 B (0%)
build/mini-cart-component-frontend.js 16.9 kB +47 B (0%)
build/mini-cart-contents-block/empty-cart-frontend.js 366 B +1 B (0%)
build/mini-cart-contents-block/filled-cart-frontend.js 230 B +1 B (0%)
build/mini-cart-contents-block/footer-frontend.js 6.99 kB +3 B (0%)
build/mini-cart-contents-block/products-table-frontend.js 291 B +2 B (+1%)
build/mini-cart-contents-block/shopping-button-frontend.js 287 B -1 B (0%)
build/mini-cart-contents.js 22.9 kB +6 B (0%)
build/price-filter-frontend.js 13.1 kB +10 B (0%)
build/price-filter.js 9.03 kB +1 B (0%)
build/product-add-to-cart.js 6.88 kB -2 B (0%)
build/product-best-sellers.js 7.71 kB -1 B (0%)
build/product-button-frontend.js 1.87 kB -4 B (0%)
build/product-categories.js 2.78 kB -3 B (0%)
build/product-category-list-frontend.js 882 B +3 B (0%)
build/product-category.js 8.69 kB +3 B (0%)
build/product-image-frontend.js 1.88 kB -3 B (0%)
build/product-new.js 7.71 kB +5 B (0%)
build/product-on-sale.js 8.02 kB +1 B (0%)
build/product-price-frontend.js 1.9 kB +4 B (0%)
build/product-rating-frontend.js 1.17 kB +2 B (0%)
build/product-rating.js 740 B -1 B (0%)
build/product-sale-badge-frontend.js 1.13 kB +1 B (0%)
build/product-search.js 2.18 kB +1 B (0%)
build/product-stock-indicator-frontend.js 996 B +2 B (0%)
build/product-summary-frontend.js 1.28 kB -2 B (0%)
build/product-tag-list-frontend.js 872 B -3 B (0%)
build/product-title-frontend.js 1.31 kB +2 B (0%)
build/product-title.js 919 B +1 B (0%)
build/products-by-attribute.js 8.63 kB -1 B (0%)
build/reviews-by-product.js 12.3 kB -4 B (0%)
build/reviews-frontend.js 7.01 kB -4 B (0%)
build/single-product-frontend.js 21.5 kB +56 B (0%)
build/single-product.js 10.1 kB +3 B (0%)
build/stock-filter-frontend.js 7.38 kB +13 B (0%)
build/stock-filter.js 7.29 kB -3 B (0%)
build/vendors--cart-blocks/order-summary-shipping--checkout-blocks/billing-address--checkout-blocks/order--5b8feb0b-frontend.js 4.85 kB +2 B (0%)
build/vendors--cart-blocks/order-summary-shipping--checkout-blocks/billing-address--checkout-blocks/order--decc3dc6-frontend.js 19.1 kB -2 B (0%)
build/vendors--product-add-to-cart-frontend.js 7.53 kB +2 B (0%)
build/wc-blocks-vendors.js 54.5 kB +4 B (0%)
ℹ️ View Unchanged
Filename Size
build/active-filters.js 7.99 kB
build/all-reviews.js 7.79 kB
build/attribute-filter.js 12.9 kB
build/blocks-checkout.js 17.4 kB
build/cart-blocks/cart-items-frontend.js 298 B
build/checkout-blocks/billing-address-frontend.js 892 B
build/general-style-rtl.css 1.29 kB
build/general-style.css 1.29 kB
build/handpicked-products.js 7.37 kB
build/mini-cart-contents-block/footer--mini-cart-contents-block/products-table-frontend.js 4.69 kB
build/mini-cart-contents-block/items-frontend.js 237 B
build/mini-cart-contents-block/title-frontend.js 367 B
build/mini-cart-frontend.js 1.72 kB
build/mini-cart.js 4.59 kB
build/price-format.js 1.19 kB
build/product-add-to-cart--product-button--product-category-list--product-image--product-price--product-r--a0326d00.js 223 B
build/product-add-to-cart--product-button--product-image--product-title.js 2.66 kB
build/product-add-to-cart-frontend.js 6.95 kB
build/product-button--product-category-list--product-image--product-price--product-rating--product-sale-b--e17c7c01.js 437 B
build/product-button--product-image--product-rating--product-sale-badge--product-title.js 302 B
build/product-button.js 1.57 kB
build/product-category-list.js 503 B
build/product-image.js 1.59 kB
build/product-price.js 1.51 kB
build/product-sale-badge.js 801 B
build/product-sku-frontend.js 380 B
build/product-sku.js 380 B
build/product-stock-indicator.js 624 B
build/product-summary.js 921 B
build/product-tag-list.js 499 B
build/product-tag.js 8.08 kB
build/product-top-rated.js 7.95 kB
build/reviews-by-category.js 11.2 kB
build/vendors--cart-blocks/cart-line-items--cart-blocks/cart-order-summary--cart-blocks/order-summary-shi--c02aad66-frontend.js 5.26 kB
build/vendors--cart-blocks/cart-line-items--checkout-blocks/order-summary-cart-items--mini-cart-contents---233ab542-frontend.js 3.14 kB
build/vendors--mini-cart-contents-block/footer-frontend.js 6.86 kB
build/wc-blocks-data.js 9.87 kB
build/wc-blocks-editor-style-rtl.css 5.04 kB
build/wc-blocks-editor-style.css 5.04 kB
build/wc-blocks-google-analytics.js 1.56 kB
build/wc-blocks-middleware.js 930 B
build/wc-blocks-registry.js 2.7 kB
build/wc-blocks-shared-context.js 1.52 kB
build/wc-blocks-shared-hocs.js 1.14 kB
build/wc-blocks-style-rtl.css 22.8 kB
build/wc-blocks-style.css 22.7 kB
build/wc-blocks-vendors-style-rtl.css 1.95 kB
build/wc-blocks-vendors-style.css 1.95 kB
build/wc-blocks.js 2.62 kB
build/wc-payment-method-bacs.js 816 B
build/wc-payment-method-cheque.js 811 B
build/wc-payment-method-cod.js 909 B
build/wc-payment-method-paypal.js 837 B
build/wc-settings.js 2.6 kB

compressed-size-action

@DAreRodz
Copy link
Collaborator

DAreRodz commented Aug 8, 2022

Hey @c4rl0sbr4v0, to prevent the <wp-block> element from being processed as a usual Woo block, and thus avoiding Woo functions to add duplicated props, try to render a block component, etc., you can add this code inside renderInnerBlocks() as a temporary solution:

diff --git a/assets/js/atomic/utils/render-parent-block.tsx b/assets/js/atomic/utils/render-parent-block.tsx
index bb6b2ecd..19d3eff4 100644
--- a/assets/js/atomic/utils/render-parent-block.tsx
+++ b/assets/js/atomic/utils/render-parent-block.tsx
@@ -141,7 +141,20 @@ const renderInnerBlocks = ( {
 	if ( ! children || children.length === 0 ) {
 		return null;
 	}
-	return Array.from( children ).map( ( node: Node, index: number ) => {
+	Array.from( children ).map( ( node: Node, index: number ) => {
+		/**
+		 * Do not process the node if its a `<wp-block>` element.
+		 */
+		if (
+			node instanceof HTMLElement &&
+			node instanceof window.customElements.get( 'wp-block' )
+		) {
+			const reactElement = parse( node.outerHTML );
+
+			if ( isValidElement( reactElement ) )
+				return cloneElement( reactElement );
+		}
+
 		/**
 		 * This will grab the blockName from the data- attributes stored in block markup. Without a blockName, we cannot
 		 * convert the HTMLElement to a React component.

That would return the JSX-representation of the <wp-block> as it is. 🙂

$block_type = $instance->block_type;
if ( ! $block_type ) {
// We might use a better way to flag it here.
wc_add_notice( 'You need to make a server registration of ' . $block['blockName'], 'error' );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can use _doing_it_wrong() here? Although that's supposed to flag a function that's invoked in the wrong way; not totally sure that applies here 🤔

Although maybe it's arguable that the render_block hook should be called with 3 args? 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @tarhi-saad just told me, they server-registered all cart inner blocks in this PR in order to fix a translation issue.

I will try to update the repo. So that way it would be fixed. Then we can discuss about adding a flag or not 😆

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah! Of course, he told me that too 😆 I'd just forgotten about it 😅

@cbravobernal cbravobernal force-pushed the try/summary-coupon-remove-block-registration branch 2 times, most recently from 3e0f77c to 1c18a86 Compare August 11, 2022 10:24
@ockham ockham force-pushed the try/summary-coupon-remove-block-registration branch from 1c18a86 to 58adfc6 Compare August 11, 2022 11:24
@cbravobernal cbravobernal force-pushed the try/summary-coupon-remove-block-registration branch from 4383989 to 29df37c Compare August 12, 2022 14:04
@cbravobernal cbravobernal marked this pull request as ready for review August 12, 2022 15:13
@ockham
Copy link
Collaborator

ockham commented Aug 12, 2022

We might also want to consider if we should change a block's save() function when migrating to our BHE technique. Currently, Woo blocks render a placeholder, e.g.

export const Save = (): JSX.Element => {
return <div { ...useBlockProps.save() } />;
};

We might want to change that to something more meaningful (that's closer to the frontend code).

@cbravobernal
Copy link
Collaborator Author

We might want to change that to something more meaningful (that's closer to the frontend code).

In this case, our registration is adding the div container the same way they do. So we may not even need a custom save.js

I used our frontend and seems to be working. Except when you reload the post editor, I'm taking a look at it 😄

@cbravobernal cbravobernal marked this pull request as draft August 16, 2022 15:42
@cbravobernal
Copy link
Collaborator Author

The error is due to the fact that the block is using useStoreCartCoupons hook.
With our approach, we share both Frontend and Save implementation, and hooks are not allowed in save function.

We have it documented here:
https://github.com/WordPress/block-hydration-experiments/blob/2d8a9ff55314e6f96a23aac535f1a91c944da213/src/gutenberg-packages/wordpress-element.js#L14

@github-actions
Copy link
Contributor

github-actions bot commented Aug 18, 2022

Script Dependencies Report

The compare-assets action has detected some changed script dependencies between this branch and trunk. Please review and confirm the following are correct before merging.

Script Handle Added Removed
cart.js react-dom ⚠️

This comment was automatically generated by the ./github/compare-assets action.

@cbravobernal cbravobernal marked this pull request as ready for review August 18, 2022 11:55
@cbravobernal
Copy link
Collaborator Author

Although we are not preventing the hydration from the parent block. I consider this PR ready for review.
We can do that task in another PR so this one won't get enormous. With this PR we are:

  • Using our little "framework" to hydrate an inner cart block. Using hooks and all working in both edit, save and frontend environments. You can apply the coupons!! 🎉
  • Skipping the save function, as with our approach, we still create a parent div with the data needed for the re-render done in Woo.

Copy link
Collaborator

@luisherranz luisherranz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually a bit surprised that this works 😄

There is a context (useValidationContext) that won't have a provider until that block is also moved to BHE, but other than that and the fact that useBlockEnvironment should not be needed in the future, it looks fine to me.


After seeing this in action, I've started thinking that Woo would probably want to keep the Save component of these blocks as mere <div> tags to avoid the problems of static block deprecations. If they use the View/Frontend component to do static rendering, they will have mismatches when they update the markup and people would have to go to the dashboard, open the Cart/Checkout page, and save the HTML again. If they use just a <div> tag (client-side rendering only), they won't have problems. Client-side rendering would cause layout shifts while loading the Cart and Checkout, though.

@cbravobernal cbravobernal merged commit 1027bd7 into trunk Aug 26, 2022
@cbravobernal cbravobernal deleted the try/summary-coupon-remove-block-registration branch August 26, 2022 14:08
@cbravobernal cbravobernal changed the title Draft: Hydrate Cart Order Summary Coupon Form inner block using BHE Hydrate Cart Order Summary Coupon Form inner block using BHE Aug 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: Prevent attribute duplication of custom block element.
4 participants