From 4c1b73169fe7c8771a727e69b68ffd623ffe495e Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Tue, 9 Apr 2024 13:15:48 -0400 Subject: [PATCH 1/3] Add skeleton component to BNPL payment messaging when element reloads --- .../bnpl-site-messaging/index.js | 52 +++++++++++++++++++ .../bnpl-site-messaging/style.scss | 34 ++++++++++-- client/product-details/index.js | 12 ++++- 3 files changed, 92 insertions(+), 6 deletions(-) diff --git a/client/product-details/bnpl-site-messaging/index.js b/client/product-details/bnpl-site-messaging/index.js index b0ebf24f054..f4784cb2bda 100644 --- a/client/product-details/bnpl-site-messaging/index.js +++ b/client/product-details/bnpl-site-messaging/index.js @@ -149,6 +149,58 @@ export const initializeBnplSiteMessaging = async () => { document .getElementById( 'payment-method-message' ) .classList.add( 'ready' ); + + // On the cart page, get the height of the PMME after it's rendered and store it in a CSS variable. This helps + // prevent layout shifts when the PMME is loaded asynchronously upon cart total update. + if ( isCart ) { + // An element that won't be removed with the cart total update. + const cartCollaterals = document.querySelector( + '.cart-collaterals' + ); + const wcBnplHeight = getComputedStyle( cartCollaterals ) + .getPropertyValue( '--wc-bnpl-height' ) + .trim(); + + if ( wcBnplHeight ) { + return; + } + + const pmme = document.getElementById( + 'payment-method-message' + ); + const pmmeContainer = document.querySelector( + '.cart_totals .__PrivateStripeElement' + ); + setTimeout( () => { + const pmmeComputedStyle = window.getComputedStyle( pmme ); + const pmmeHeight = parseFloat( pmmeComputedStyle.height ); + const pmmeMarginBottom = parseFloat( bottomMargin ); + const pmmeTotalHeight = pmmeHeight + pmmeMarginBottom; + + const pmmeContainerComputedStyle = window.getComputedStyle( + pmmeContainer + ); + const pmmeContainerHeight = parseFloat( + pmmeContainerComputedStyle.height + ); + + cartCollaterals.style.setProperty( + '--wc-bnpl-height', + pmmeTotalHeight + 'px' + ); + cartCollaterals.style.setProperty( + '--wc-bnpl-container-height', + pmmeContainerHeight - 12 + 'px' + ); + + cartCollaterals.style.setProperty( + '--wc-bnpl-loader-margin', + pmmeMarginBottom + 2 + 'px' + ); + + pmme.style.setProperty( '--wc-bnpl-margin-bottom', '-4px' ); + }, '1000' ); + } } ); } diff --git a/client/product-details/bnpl-site-messaging/style.scss b/client/product-details/bnpl-site-messaging/style.scss index 6ae65d7555c..243ea0d777d 100644 --- a/client/product-details/bnpl-site-messaging/style.scss +++ b/client/product-details/bnpl-site-messaging/style.scss @@ -17,13 +17,37 @@ } .cart_totals { - &:has( + #payment-method-message.ready ) { - margin-bottom: 0; + #payment-method-message { + margin: -8px 0 4px; + height: var( --wc-bnpl-height ); + padding: 2px 1em 0; + margin-bottom: var( --wc-bnpl-margin-bottom ); + + &.pmme-updated { + margin: -12px 0 0; + padding: 0 1em; + } + + &.skeleton { + margin-bottom: 4px; + background: #afafaf; + } } - #payment-method-message.ready { - margin-bottom: var( --wc-bnpl-margin-bottom ); - padding: 0 1em; + .pmme-loading { + animation: pmme-loading 1s linear infinite alternate; + background: #afafaf; + height: var( --wc-bnpl-container-height ); + margin: -4px 1em var( --wc-bnpl-loader-margin ) 1em; + } +} + +@keyframes pmme-loading { + 0% { + background-color: hsl( 204, 10%, 90% ); + } + 100% { + background-color: hsl( 200, 20%, 95% ); } } diff --git a/client/product-details/index.js b/client/product-details/index.js index 4ed333ad46d..0591b84e794 100644 --- a/client/product-details/index.js +++ b/client/product-details/index.js @@ -126,9 +126,19 @@ jQuery( async function ( $ ) { } ); $( document.body ).on( 'updated_cart_totals', () => { + $( '#payment-method-message' ).before( + '
' + ); + $( '#payment-method-message' ).hide(); bnplGetCartTotal().then( ( response ) => { window.wcpayStripeSiteMessaging.cartTotal = response.total; - initializeBnplSiteMessaging(); + initializeBnplSiteMessaging().then( () => { + setTimeout( () => { + $( '.pmme-loading' ).remove(); + $( '#payment-method-message' ).show(); + $( '#payment-method-message' ).addClass( 'pmme-updated' ); + }, 1000 ); + } ); } ); } ); From f4cb636b14be6973bee5ec00aee56813a5615494 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Tue, 9 Apr 2024 13:20:22 -0400 Subject: [PATCH 2/3] changelog --- changelog/cart-pmme-total-updates | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/cart-pmme-total-updates diff --git a/changelog/cart-pmme-total-updates b/changelog/cart-pmme-total-updates new file mode 100644 index 00000000000..d1a3379da0f --- /dev/null +++ b/changelog/cart-pmme-total-updates @@ -0,0 +1,5 @@ +Significance: patch +Type: add +Comment: Adding skeleton component to BNPL messaging on cart page which has not yet been deployed. + + From 23bcf55f89387e93684b6fbe42efb5a3e295f149 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Wed, 10 Apr 2024 11:48:20 -0400 Subject: [PATCH 3/3] Increase delay before applying CSS variables and use correct type for delay --- client/product-details/bnpl-site-messaging/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/product-details/bnpl-site-messaging/index.js b/client/product-details/bnpl-site-messaging/index.js index f4784cb2bda..a93981f5ef1 100644 --- a/client/product-details/bnpl-site-messaging/index.js +++ b/client/product-details/bnpl-site-messaging/index.js @@ -199,7 +199,7 @@ export const initializeBnplSiteMessaging = async () => { ); pmme.style.setProperty( '--wc-bnpl-margin-bottom', '-4px' ); - }, '1000' ); + }, 2000 ); } } ); }