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

Integrate express payments buttonAttributes API from the Checkout Block #8888

Merged
merged 23 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
cb69a58
Respect button size, theme and label from the express checkout block
alexflorisca May 20, 2024
2586edb
Only respect buttonAttribute when available
alexflorisca May 29, 2024
6ebab87
Height not in px anymore
alexflorisca May 29, 2024
c588fef
Add px back in the style prop
alexflorisca May 29, 2024
93a14bc
Update client/checkout/woopay/express-button/woopay-express-checkout-…
alexflorisca Jun 3, 2024
d0951e5
safer type checking
alexflorisca Jun 3, 2024
ca158f0
Merge develop
alexflorisca Aug 12, 2024
0ba5be0
Fix typo and add tests
alexflorisca Aug 12, 2024
de470e8
Changelog
alexflorisca Aug 12, 2024
421ab6d
Add admin notice
alexflorisca Aug 12, 2024
b917a9b
Update admin notice
alexflorisca Aug 13, 2024
33b6eec
Update admin notice
alexflorisca Aug 13, 2024
2abb118
Add buttonAttributes to ECE component
alexflorisca Aug 19, 2024
578c9e6
Cast to Number
alexflorisca Aug 19, 2024
8666f15
Merge branch 'develop' into try/poc-express-checkout-button-styles
alexflorisca Aug 20, 2024
dcdb55c
fix wcpaySettings undefined issue
reykjalin Aug 23, 2024
b90b69a
Merge branch 'develop' into try/poc-express-checkout-button-styles
reykjalin Aug 23, 2024
7886e27
Cap buttonHeight at 55px max
alexflorisca Sep 3, 2024
d647bd0
Merge branch 'develop' into try/poc-express-checkout-button-styles
alexflorisca Sep 3, 2024
01c2795
Remove darkMode
alexflorisca Sep 3, 2024
6064546
add data-size back in
alexflorisca Sep 6, 2024
7f623fe
Remove checkout link from settings page
alexflorisca Sep 10, 2024
49eaf8c
Merge branch 'develop' into try/poc-express-checkout-button-styles
alexflorisca Sep 10, 2024
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
4 changes: 4 additions & 0 deletions changelog/add-express-payment-button-styles
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Add compatibility with the buttonAttributes API from Woo Blocks
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,27 @@ describe( 'WoopayExpressCheckoutButton', () => {
).toBeInTheDocument();
} );

test( 'respect buttonAttributes API when available ', () => {
render(
<WoopayExpressCheckoutButton
isPreview={ false }
buttonSettings={ buttonSettings }
api={ api }
isProductPage={ false }
emailSelector="#email"
buttonAttributes={ {
height: '55',
borderRadius: '20',
} }
/>
);

const button = screen.queryByRole( 'button', { name: 'WooPay' } );
expect( button.getAttribute( 'style' ) ).toBe(
'height: 55px; border-radius: 20px;'
);
} );

test( 'does not prefetch session data by default', async () => {
getConfig.mockImplementation( ( v ) => {
switch ( v ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const WoopayExpressCheckoutButton = ( {
api,
isProductPage = false,
emailSelector = '#email',
buttonAttributes,
} ) => {
const buttonWidthTypes = {
narrow: 'narrow',
Expand All @@ -48,10 +49,9 @@ export const WoopayExpressCheckoutButton = ( {
const onClickCallbackRef = useRef( null );
const buttonRef = useRef( null );
const isLoadingRef = useRef( false );
const {
let {
height: buttonHeight,
type: buttonType,
height,
size,
theme,
context,
radius: borderRadius,
Expand All @@ -60,6 +60,18 @@ export const WoopayExpressCheckoutButton = ( {
const [ buttonWidthType, setButtonWidthType ] = useState(
buttonWidthTypes.wide
);
const buttonSizeMap = new Map();
buttonSizeMap.set( '40', 'small' );
buttonSizeMap.set( '48', 'medium' );
buttonSizeMap.set( '55', 'large' );

// If we are on the checkout block, we receive button attributes which overwrite the extension specific settings
if ( typeof buttonAttributes !== 'undefined' ) {
buttonHeight = buttonAttributes.height || buttonHeight;
borderRadius = buttonAttributes.borderRadius || borderRadius;
}

const buttonSize = buttonSizeMap.get( buttonHeight );

const buttonText =
ButtonTypeTextMap[ buttonType || 'default' ] ??
Expand Down Expand Up @@ -353,18 +365,18 @@ export const WoopayExpressCheckoutButton = ( {
return (
<button
ref={ buttonRef }
key={ `${ buttonType }-${ theme }-${ size }` }
key={ `${ buttonType }-${ theme }-${ buttonSize }` }
aria-label={ buttonText }
onClick={ ( e ) => onClickCallbackRef.current( e ) }
className={ classNames( 'woopay-express-button', {
'is-loading': isLoading,
} ) }
data-type={ buttonType }
data-size={ size }
alexflorisca marked this conversation as resolved.
Show resolved Hide resolved
data-size={ buttonSize }
data-theme={ theme }
data-width-type={ buttonWidthType }
style={ {
height: `${ height }px`,
height: `${ buttonHeight }px`,
borderRadius: `${ borderRadius }px`,
} }
disabled={ isLoading }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,24 @@ const api = new WCPayAPI(
request
);

const WooPayExpressCheckoutButtonContainer = () => {
const onRefChange = useCallback( ( node ) => {
if ( node ) {
const root = ReactDOM.createRoot( node );
const WooPayExpressCheckoutButtonContainer = ( { buttonAttributes } ) => {
const onRefChange = useCallback(
( node ) => {
if ( node ) {
const root = ReactDOM.createRoot( node );

root.render(
<WoopayExpressCheckoutButton
buttonSettings={ getConfig( 'woopayButton' ) }
api={ api }
emailSelector="#email"
/>
);
}
}, [] );
root.render(
<WoopayExpressCheckoutButton
buttonSettings={ getConfig( 'woopayButton' ) }
api={ api }
emailSelector="#email"
buttonAttributes={ buttonAttributes }
/>
);
}
},
[ buttonAttributes ]
);

return <span ref={ onRefChange } />;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ const ExpressCheckoutComponent = ( {
onClick,
onClose,
expressPaymentMethod = '',
buttonAttributes,
} ) => {
const {
buttonOptions,
Expand Down Expand Up @@ -116,10 +117,27 @@ const ExpressCheckoutComponent = ( {
onReady( event );
};

// The Cart & Checkout blocks provide unified styles across all buttons,
// which should override the extension specific settings.
const withBlockOverride = () => {
const override = {};
if ( typeof buttonAttributes !== 'undefined' ) {
override.buttonHeight = Number( buttonAttributes.height );
}
return {
...buttonOptions,
...override,
};
};

return (
<ExpressCheckoutElement
options={ {
...adjustButtonHeights( buttonOptions, expressPaymentMethod ),
...withBlockOverride( buttonOptions ),
...adjustButtonHeights(
withBlockOverride( buttonOptions ),
expressPaymentMethod
),
...getPaymentMethodsOverride( expressPaymentMethod ),
} }
onClick={ onButtonClick }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { getExpressCheckoutButtonAppearance } from 'wcpay/express-checkout/utils
import '../express-checkout-element.scss';

const ExpressCheckoutContainer = ( props ) => {
const { api, billing } = props;
const { api, billing, buttonAttributes } = props;

const stripePromise = useMemo( () => {
return api.loadStripe( true );
Expand All @@ -23,7 +23,7 @@ const ExpressCheckoutContainer = ( props ) => {
paymentMethodCreation: 'manual',
amount: billing.cartTotal.value,
currency: billing.currency.code.toLowerCase(),
appearance: getExpressCheckoutButtonAppearance(),
appearance: getExpressCheckoutButtonAppearance( buttonAttributes ),
};

return (
Expand Down
21 changes: 17 additions & 4 deletions client/express-checkout/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,18 +169,31 @@ export const displayLoginConfirmation = (
}
};

type ButtonAttributesType =
| { height: string; borderRadius: string }
| undefined;

/**
* Returns the appearance settings for the Express Checkout buttons.
* Currently only configures border radius for the buttons.
*/
export const getExpressCheckoutButtonAppearance = () => {
export const getExpressCheckoutButtonAppearance = (
buttonAttributes: ButtonAttributesType
) => {
let borderRadius = getDefaultBorderRadius();
Copy link
Member Author

Choose a reason for hiding this comment

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

For me this generates an error locally, saying wcpaySettings is undefined. Not quite sure where to go with it, seems like it should be exported as a global but it's not there 🤷

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I'm seeing the same thing. It started happening as soon as you added getDefaultBorderRadius() there in 2abb118 and I think it's uncovering a bad assumption from when we added the utility function.

It seems wcpaySettings isn't always loaded (like we expected while adding support for ECE) but we never got an issue because the previous version of getExpressCheckoutButtonAppearance never actually called getDefaultBorderRadius. The border radius was always present on wcpayExpressCheckoutParams.button.

I pushed a fix for this in dcdb55c 👍

const buttonSettings = getExpressCheckoutData( 'button' );

// Border radius from WooPayments settings
borderRadius = buttonSettings?.radius ?? borderRadius;

// Border radius from Cart & Checkout blocks attributes
if ( typeof buttonAttributes !== 'undefined' ) {
borderRadius = Number( buttonAttributes?.borderRadius ) ?? borderRadius;
}

return {
variables: {
borderRadius: `${
buttonSettings?.radius || getDefaultBorderRadius()
}px`,
borderRadius: `${ borderRadius }px`,
spacingUnit: '6px',
},
};
Expand Down
12 changes: 9 additions & 3 deletions client/payment-request/blocks/payment-request-express.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { Elements, PaymentRequestButtonElement } from '@stripe/react-stripe-js';
* Internal dependencies
*/
import { useInitialization } from './use-initialization';
import { getPaymentRequestData } from '../utils';
import { recordUserEvent } from 'tracks';
import { useEffect, useState } from 'react';
import { getPaymentRequestData } from '../utils/utils';

/**
* PaymentRequestExpressComponent
Expand All @@ -28,6 +28,7 @@ const PaymentRequestExpressComponent = ( {
onClick,
onClose,
onPaymentRequestAvailable,
buttonAttributes,
} ) => {
// TODO: Don't display custom button when result.requestType
// is `apple_pay` or `google_pay`.
Expand All @@ -44,13 +45,18 @@ const PaymentRequestExpressComponent = ( {
onClose,
} );

const { type, theme, height } = getPaymentRequestData( 'button' );
let { type, theme, height } = getPaymentRequestData( 'button' );

// If we are on the checkout block, we receive button attributes which overwrite the extension specific settings
if ( typeof buttonAttributes !== 'undefined' ) {
height = buttonAttributes.height || height;
}

const paymentRequestButtonStyle = {
paymentRequestButton: {
type,
theme,
height: height + 'px',
height: `${ height }px`,
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,20 +168,31 @@ const GeneralPaymentRequestButtonSettings = ( { type } ) => {
return (
<CardBody>
{ showWarning && (
<InlineNotice
status="warning"
icon={ true }
isDismissible={ false }
>
{ sprintf(
/* translators: %s type of button to which the settings will be applied */
__(
'These settings will also apply to the %s on your store.',
'woocommerce-payments'
),
otherButtons
) }
</InlineNotice>
<>
<InlineNotice
status="warning"
icon={ true }
isDismissible={ false }
>
{ sprintf(
/* translators: %s type of button to which the settings will be applied */
__(
'These settings will also apply to the %s on your store.',
'woocommerce-payments'
),
otherButtons
) }
</InlineNotice>
<InlineNotice
status="warning"
icon={ true }
isDismissible={ false }
>
{ __(
'Some appearance settings may be overridden in the express payment section of the Cart & Checkout blocks.'
) }
</InlineNotice>
</>
) }
<h4>{ __( 'Call to action', 'woocommerce-payments' ) }</h4>
<SelectControl
Expand Down
6 changes: 6 additions & 0 deletions client/utils/express-checkout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export const getExpressCheckoutConfig = ( key ) => {
};

export const getDefaultBorderRadius = () => {
// If wcpaySettings isn't loaded on the page where this is called we can
// safely return the default value of 4.
if ( typeof wcpaySettings === 'undefined' ) {
return 4;
}

return parseInt(
window?.wcpaySettings?.defaultExpressCheckoutBorderRadius || 4,
10
Expand Down
Loading