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

Show Express Checkout button previews in editor #10141

Open
wants to merge 24 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
63184d1
Show Express Checkout button previews in editor when the elements do …
danielmx-dev Jan 13, 2025
ff760c9
Merge branch 'develop' into fix/show-preview-for-express-checkout-but…
danielmx-dev Jan 16, 2025
b2837a7
Merge branch 'develop' into fix/show-preview-for-express-checkout-but…
danielmx-dev Jan 16, 2025
432fd73
Add changelog
danielmx-dev Jan 16, 2025
f2ee578
Rename component
danielmx-dev Jan 16, 2025
36a4544
Use google pay library directly to render test buttons
danielmx-dev Jan 16, 2025
5e94840
Add onClick parameter
danielmx-dev Jan 16, 2025
1fe5984
Apply border radius changes
danielmx-dev Jan 16, 2025
2d27578
Use correct reference
danielmx-dev Jan 16, 2025
60f6cb2
Merge branch 'develop' into fix/show-preview-for-express-checkout-but…
frosso Jan 17, 2025
b087475
Merge branch 'develop' into fix/show-preview-for-express-checkout-but…
frosso Jan 21, 2025
eca4c98
Merge branch 'develop' into fix/show-preview-for-express-checkout-but…
danielmx-dev Jan 22, 2025
8b9986c
Refactor hooks
danielmx-dev Jan 22, 2025
987368a
Add button types to the previews
danielmx-dev Jan 22, 2025
bc6a1a0
Always display the preview component when isPreview is true
danielmx-dev Jan 22, 2025
aaa14f8
Remove unnecessary styles
danielmx-dev Jan 22, 2025
d327efb
Merge branch 'develop' into fix/show-preview-for-express-checkout-but…
danielmx-dev Jan 24, 2025
3fa843e
Fix issue with outline theme
danielmx-dev Jan 24, 2025
0301252
Separate components
danielmx-dev Jan 24, 2025
d22ea91
Remove conditional assignment for onClick handler
danielmx-dev Jan 24, 2025
13de3e2
Merge branch 'develop' into fix/show-preview-for-express-checkout-but…
danielmx-dev Jan 28, 2025
f26c0ad
Only use the preview components if the express payment method is supp…
danielmx-dev Jan 30, 2025
5babdc1
Merge branch 'develop' into fix/show-preview-for-express-checkout-but…
danielmx-dev Jan 30, 2025
b0abd9b
Merge branch 'develop' into fix/show-preview-for-express-checkout-but…
danielmx-dev Feb 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: fix

Show Express Checkout button previews in template editor
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/**
* External dependencies
*/
import { useEffect, useRef } from 'react';

/**
* Internal dependencies
*/
import { getExpressCheckoutButtonAppearance } from '../../utils';

export const SUPPORTED_PREVIEW_PAYMENT_METHODS = [ 'googlePay', 'applePay' ];

const GooglePayButtonPreview = ( { options, buttonAttributes, theme } ) => {
const googlePlayContainerRef = useRef( null );
const hasStartedLoadingGooglePlayButton = useRef( null );
const appearance = getExpressCheckoutButtonAppearance( buttonAttributes );
const borderRadius = appearance.variables.borderRadius;

useEffect( () => {
if (
googlePlayContainerRef.current &&
! hasStartedLoadingGooglePlayButton.current
) {
hasStartedLoadingGooglePlayButton.current = true;
( async () => {
// The container may be inside an iframe, so we need to retrieve a reference to the document and window objects.
const targetDocument =
googlePlayContainerRef.current.ownerDocument;
const targetWindow = targetDocument.defaultView;
if ( ! targetWindow.google?.payments?.api?.PaymentsClient ) {
await new Promise( ( resolve ) => {
const script = document.createElement( 'script' );
script.src = 'https://pay.google.com/gp/p/js/pay.js';
script.onload = resolve;
targetDocument.head.appendChild( script );
} );
}

const googlePayClient = new targetWindow.google.payments.api.PaymentsClient(
{
environment: 'TEST',
}
);

const buttonColor = theme === 'black' ? 'black' : 'white'; // There is no 'outline' theme in Google Pay.

const button = googlePayClient.createButton( {
buttonType: options.buttonType.googlePay,
buttonColor,
buttonRadius: parseFloat( borderRadius ),
buttonSizeMode: 'fill',
onClick: () => {},
} );
googlePlayContainerRef.current.appendChild( button );
} )();
}
}, [ theme, borderRadius, options.buttonType.googlePay ] );

useEffect( () => {
googlePlayContainerRef.current
?.querySelector( 'button' )
?.style?.setProperty( 'border-radius', borderRadius );
}, [ borderRadius ] );

return (
<div
ref={ googlePlayContainerRef }
id="express-checkout-button-preview-googlePay"
style={ {
height: `${ options.buttonHeight }px`,
width: '100%',
} }
/>
);
};

const ApplePayButtonPreview = ( { options, buttonAttributes, theme } ) => {
const appearance = getExpressCheckoutButtonAppearance( buttonAttributes );
const borderRadius = appearance.variables.borderRadius;

const buttonStyle = {
height: `${ options.buttonHeight }px`,
borderRadius,
ApplePayButtonType: options.buttonType.applePay,
WebkitAppearance: '-apple-pay-button',
width: '100%',
};

if ( [ 'black', 'white', 'white-outline' ].includes( theme ) ) {
buttonStyle.ApplePayButtonStyle = theme;
} else {
buttonStyle.ApplePayButtonStyle = 'white';
}

return (
<div>
<button
type="button"
id="express-checkout-button-preview-applePay"
className="express-checkout-button-preview"
style={ buttonStyle }
/>
</div>
);
};

const ExpressCheckoutButtonPreview = ( {
expressPaymentMethod,
options,
buttonAttributes,
} ) => {
const theme = options.buttonTheme[ expressPaymentMethod ];

if ( expressPaymentMethod === 'googlePay' ) {
return (
<GooglePayButtonPreview
options={ options }
buttonAttributes={ buttonAttributes }
theme={ theme }
/>
);
}

if ( expressPaymentMethod === 'applePay' ) {
return (
<ApplePayButtonPreview
options={ options }
buttonAttributes={ buttonAttributes }
theme={ theme }
/>
);
}

return null;
};

export default ExpressCheckoutButtonPreview;
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import {
} from '../../event-handlers';
import { useExpressCheckout } from '../hooks/use-express-checkout';
import { PAYMENT_METHOD_NAME_EXPRESS_CHECKOUT_ELEMENT } from 'wcpay/checkout/constants';
import ExpressCheckoutButtonPreview, {
SUPPORTED_PREVIEW_PAYMENT_METHODS,
} from './express-checkout-button-preview';

const getPaymentMethodsOverride = ( enabledPaymentMethod ) => {
const allDisabled = {
Expand Down Expand Up @@ -131,16 +134,28 @@ const ExpressCheckoutComponent = ( {
};
};

const checkoutElementOptions = {
...withBlockOverride(),
...adjustButtonHeights( withBlockOverride(), expressPaymentMethod ),
...getPaymentMethodsOverride( expressPaymentMethod ),
};

if (
isPreview &&
SUPPORTED_PREVIEW_PAYMENT_METHODS.includes( expressPaymentMethod )
) {
return (
<ExpressCheckoutButtonPreview
expressPaymentMethod={ expressPaymentMethod }
buttonAttributes={ buttonAttributes }
options={ checkoutElementOptions }
/>
);
}

return (
<ExpressCheckoutElement
options={ {
...withBlockOverride(),
...adjustButtonHeights(
withBlockOverride(),
expressPaymentMethod
),
...getPaymentMethodsOverride( expressPaymentMethod ),
} }
options={ checkoutElementOptions }
onClick={ onClickHandler }
onConfirm={ onConfirm }
onReady={ onElementsReady }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,11 @@
margin-left: 1px !important;
width: 99% !important;
}

// Preview button
@supports not ( -webkit-appearance: -apple-pay-button ) {
/* stylelint-disable-next-line selector-id-pattern */
#express-payment-method-woocommerce_payments_express_checkout_applePay:has( #express-checkout-button-preview-applePay ) {
display: none;
}
}
Loading