Skip to content

Commit

Permalink
Fix UPE styles extraction in the Site Editor (#10433)
Browse files Browse the repository at this point in the history
Co-authored-by: Francesco <[email protected]>
  • Loading branch information
danielmx-dev and frosso authored Feb 27, 2025
1 parent 2f84fc8 commit 0bf5df6
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 146 deletions.
4 changes: 4 additions & 0 deletions changelog/fix-style-extraction-in-editor
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: fix

Properly extract styles when using the site editor.
96 changes: 55 additions & 41 deletions client/checkout/blocks/payment-elements.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { useEffect, useState, RawHTML } from '@wordpress/element';
import { useEffect, useState, RawHTML, useRef } from '@wordpress/element';
import { Elements } from '@stripe/react-stripe-js';
// eslint-disable-next-line import/no-unresolved
import { StoreNotice } from '@woocommerce/blocks-checkout';
Expand All @@ -20,6 +20,7 @@ import { getPaymentMethodTypes } from 'wcpay/checkout/utils/upe';

const PaymentElements = ( { api, ...props } ) => {
const stripeForUPE = useStripeForUPE( api, props.paymentMethodId );
const containerRef = useRef( null );

const [ errorMessage, setErrorMessage ] = useState( null );
const [
Expand All @@ -29,16 +30,27 @@ const PaymentElements = ( { api, ...props } ) => {
const [ appearance, setAppearance ] = useState(
getUPEConfig( 'wcBlocksUPEAppearance' )
);
const [ fontRules ] = useState( getFontRulesFromPage() );
const [ fontRules, setFontRules ] = useState( [] );

const [ fingerprint, fingerprintErrorMessage ] = useFingerprint();
const amount = Number( getUPEConfig( 'cartTotal' ) );
const currency = getUPEConfig( 'currency' ).toLowerCase();
const paymentMethodTypes = getPaymentMethodTypes( props.paymentMethodId );

useEffect( () => {
async function generateUPEAppearance() {
if ( ! containerRef.current ) {
return;
}
setFontRules(
getFontRulesFromPage( containerRef.current.ownerDocument )
);
// Generate UPE input styles.
let upeAppearance = getAppearance( 'blocks_checkout', false );
let upeAppearance = getAppearance(
'blocks_checkout',
false,
containerRef.current.ownerDocument
);
upeAppearance = await api.saveUPEAppearance(
upeAppearance,
'blocks_checkout'
Expand All @@ -61,46 +73,48 @@ const PaymentElements = ( { api, ...props } ) => {
props.paymentMethodId,
] );

if ( ! stripeForUPE ) {
return <LoadableBlock isLoading numLines={ 3 }></LoadableBlock>;
}

return (
<LoadableBlock isLoading={ ! appearance } numLines={ 3 }>
<Elements
stripe={ stripeForUPE }
options={ {
mode: amount < 1 ? 'setup' : 'payment',
amount: amount,
currency: currency,
paymentMethodCreation: 'manual',
paymentMethodTypes: paymentMethodTypes,
appearance: appearance,
fonts: fontRules,
} }
<>
<LoadableBlock
isLoading={ ! appearance || ! stripeForUPE }
numLines={ 3 }
>
{ paymentProcessorLoadErrorMessage?.error?.message && (
<div className="wc-block-components-notices">
<StoreNotice status="error" isDismissible={ false }>
<RawHTML>
{
paymentProcessorLoadErrorMessage.error
.message
}
</RawHTML>
</StoreNotice>
</div>
) }
<PaymentProcessor
api={ api }
errorMessage={ errorMessage }
fingerprint={ fingerprint }
onLoadError={ setPaymentProcessorLoadErrorMessage }
theme={ appearance?.theme }
{ ...props }
/>
</Elements>
</LoadableBlock>
<Elements
stripe={ stripeForUPE }
options={ {
mode: amount < 1 ? 'setup' : 'payment',
amount: amount,
currency: currency,
paymentMethodCreation: 'manual',
paymentMethodTypes: paymentMethodTypes,
appearance: appearance,
fonts: fontRules,
} }
>
{ paymentProcessorLoadErrorMessage?.error?.message && (
<div className="wc-block-components-notices">
<StoreNotice status="error" isDismissible={ false }>
<RawHTML>
{
paymentProcessorLoadErrorMessage.error
.message
}
</RawHTML>
</StoreNotice>
</div>
) }
<PaymentProcessor
api={ api }
errorMessage={ errorMessage }
fingerprint={ fingerprint }
onLoadError={ setPaymentProcessorLoadErrorMessage }
theme={ appearance?.theme }
{ ...props }
/>
</Elements>
</LoadableBlock>
<div ref={ containerRef } />
</>
);
};

Expand Down
19 changes: 15 additions & 4 deletions client/checkout/blocks/payment-method-label.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useStripeForUPE } from 'wcpay/hooks/use-stripe-async';
import { getUPEConfig } from 'wcpay/utils/checkout';
import { __ } from '@wordpress/i18n';
import './style.scss';
import { useEffect, useMemo, useState } from '@wordpress/element';
import { useEffect, useState, useRef } from '@wordpress/element';
import { getAppearance, getFontRulesFromPage } from 'wcpay/checkout/upe-styles';

const paymentMethods = [
Expand Down Expand Up @@ -78,6 +78,7 @@ const PaymentMethodMessageWrapper = ( {
};

export default ( { api, title, countries, iconLight, iconDark, upeName } ) => {
const containerRef = useRef( null );
const cartData = wp.data.select( 'wc/store/cart' ).getCartData();
const isTestMode = getUPEConfig( 'testMode' );
const [ appearance, setAppearance ] = useState(
Expand All @@ -88,7 +89,7 @@ export default ( { api, title, countries, iconLight, iconDark, upeName } ) => {
getUPEConfig( 'wcBlocksUPEAppearanceTheme' )
);

const fontRules = useMemo( () => getFontRulesFromPage(), [] );
const [ fontRules, setFontRules ] = useState( [] );

// Stripe expects the amount to be sent as the minor unit of 2 digits.
const amount = parseInt(
Expand All @@ -107,8 +108,18 @@ export default ( { api, title, countries, iconLight, iconDark, upeName } ) => {

useEffect( () => {
async function generateUPEAppearance() {
if ( ! containerRef.current ) {
return;
}
setFontRules(
getFontRulesFromPage( containerRef.current.ownerDocument )
);
// Generate UPE input styles.
let upeAppearance = getAppearance( 'blocks_checkout', false );
let upeAppearance = getAppearance(
'blocks_checkout',
false,
containerRef.current.ownerDocument
);
upeAppearance = await api.saveUPEAppearance(
upeAppearance,
'blocks_checkout'
Expand All @@ -130,7 +141,7 @@ export default ( { api, title, countries, iconLight, iconDark, upeName } ) => {

return (
<>
<div className="payment-method-label">
<div ref={ containerRef } className="payment-method-label">
<span className="payment-method-label__label">{ title }</span>
{ isTestMode && (
<span className="test-mode badge">
Expand Down
Loading

0 comments on commit 0bf5df6

Please sign in to comment.