-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: ECE copy for tokenized cart implementation (#9730)
- Loading branch information
Showing
27 changed files
with
3,071 additions
and
99 deletions.
There are no files selected for viewing
5 changes: 5 additions & 0 deletions
5
changelog/chore-copy-of-express-checkout-ece-for-tokenized-feature-flag
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Significance: patch | ||
Type: add | ||
Comment: chore: create copy of ECE for tokenized cart feature flag | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
154 changes: 154 additions & 0 deletions
154
client/tokenized-express-checkout/blocks/components/express-checkout-component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { ExpressCheckoutElement } from '@stripe/react-stripe-js'; | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
shippingAddressChangeHandler, | ||
shippingRateChangeHandler, | ||
} from '../../event-handlers'; | ||
import { useExpressCheckout } from '../hooks/use-express-checkout'; | ||
import { PAYMENT_METHOD_NAME_EXPRESS_CHECKOUT_ELEMENT } from 'wcpay/checkout/constants'; | ||
|
||
const getPaymentMethodsOverride = ( enabledPaymentMethod ) => { | ||
const allDisabled = { | ||
amazonPay: 'never', | ||
applePay: 'never', | ||
googlePay: 'never', | ||
link: 'never', | ||
paypal: 'never', | ||
}; | ||
|
||
const enabledParam = [ 'applePay', 'googlePay' ].includes( | ||
enabledPaymentMethod | ||
) | ||
? 'always' | ||
: 'auto'; | ||
|
||
return { | ||
paymentMethods: { | ||
...allDisabled, | ||
[ enabledPaymentMethod ]: enabledParam, | ||
}, | ||
}; | ||
}; | ||
|
||
// Visual adjustments to horizontally align the buttons. | ||
const adjustButtonHeights = ( buttonOptions, expressPaymentMethod ) => { | ||
// Apple Pay has a nearly imperceptible height difference. We increase it by 1px here. | ||
if ( buttonOptions.buttonTheme.applePay === 'black' ) { | ||
if ( expressPaymentMethod === 'applePay' ) { | ||
buttonOptions.buttonHeight = buttonOptions.buttonHeight + 0.4; | ||
} | ||
} | ||
|
||
// GooglePay with the white theme has a 2px height difference due to its border. | ||
if ( | ||
expressPaymentMethod === 'googlePay' && | ||
buttonOptions.buttonTheme.googlePay === 'white' | ||
) { | ||
buttonOptions.buttonHeight = buttonOptions.buttonHeight - 2; | ||
} | ||
|
||
// Clamp the button height to the allowed range 40px to 55px. | ||
buttonOptions.buttonHeight = Math.max( | ||
40, | ||
Math.min( buttonOptions.buttonHeight, 55 ) | ||
); | ||
return buttonOptions; | ||
}; | ||
|
||
/** | ||
* ExpressCheckout express payment method component. | ||
* | ||
* @param {Object} props PaymentMethodProps. | ||
* | ||
* @return {ReactNode} Stripe Elements component. | ||
*/ | ||
const ExpressCheckoutComponent = ( { | ||
api, | ||
billing, | ||
shippingData, | ||
setExpressPaymentError, | ||
onClick, | ||
onClose, | ||
expressPaymentMethod = '', | ||
buttonAttributes, | ||
isPreview = false, | ||
} ) => { | ||
const { | ||
buttonOptions, | ||
onButtonClick, | ||
onConfirm, | ||
onReady, | ||
onCancel, | ||
elements, | ||
} = useExpressCheckout( { | ||
api, | ||
billing, | ||
shippingData, | ||
onClick, | ||
onClose, | ||
setExpressPaymentError, | ||
} ); | ||
const onClickHandler = ! isPreview ? onButtonClick : () => {}; | ||
const onShippingAddressChange = ( event ) => | ||
shippingAddressChangeHandler( api, event, elements ); | ||
|
||
const onShippingRateChange = ( event ) => | ||
shippingRateChangeHandler( api, event, elements ); | ||
|
||
const onElementsReady = ( event ) => { | ||
const paymentMethodContainer = document.getElementById( | ||
`express-payment-method-${ PAYMENT_METHOD_NAME_EXPRESS_CHECKOUT_ELEMENT }_${ expressPaymentMethod }` | ||
); | ||
|
||
const availablePaymentMethods = event.availablePaymentMethods || {}; | ||
|
||
if ( | ||
paymentMethodContainer && | ||
! availablePaymentMethods[ expressPaymentMethod ] | ||
) { | ||
paymentMethodContainer.remove(); | ||
} | ||
|
||
// Any actions that WooPayments needs to perform. | ||
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={ { | ||
...withBlockOverride( buttonOptions ), | ||
...adjustButtonHeights( | ||
withBlockOverride( buttonOptions ), | ||
expressPaymentMethod | ||
), | ||
...getPaymentMethodsOverride( expressPaymentMethod ), | ||
} } | ||
onClick={ onClickHandler } | ||
onConfirm={ onConfirm } | ||
onReady={ onElementsReady } | ||
onCancel={ onCancel } | ||
onShippingAddressChange={ onShippingAddressChange } | ||
onShippingRateChange={ onShippingRateChange } | ||
/> | ||
); | ||
}; | ||
|
||
export default ExpressCheckoutComponent; |
42 changes: 42 additions & 0 deletions
42
client/tokenized-express-checkout/blocks/components/express-checkout-container.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { useMemo } from 'react'; | ||
import { Elements } from '@stripe/react-stripe-js'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import ExpressCheckoutComponent from './express-checkout-component'; | ||
import { | ||
getExpressCheckoutButtonAppearance, | ||
getExpressCheckoutData, | ||
} from 'wcpay/express-checkout/utils'; | ||
import '../express-checkout-element.scss'; | ||
|
||
const ExpressCheckoutContainer = ( props ) => { | ||
const { api, billing, buttonAttributes, isPreview } = props; | ||
|
||
const stripePromise = useMemo( () => { | ||
return api.loadStripeForExpressCheckout(); | ||
}, [ api ] ); | ||
|
||
const options = { | ||
mode: 'payment', | ||
paymentMethodCreation: 'manual', | ||
amount: ! isPreview ? billing.cartTotal.value : 10, | ||
currency: ! isPreview ? billing.currency.code.toLowerCase() : 'usd', | ||
appearance: getExpressCheckoutButtonAppearance( buttonAttributes ), | ||
locale: getExpressCheckoutData( 'stripe' )?.locale ?? 'en', | ||
}; | ||
|
||
return ( | ||
<div style={ { minHeight: '40px' } }> | ||
<Elements stripe={ stripePromise } options={ options }> | ||
<ExpressCheckoutComponent { ...props } /> | ||
</Elements> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ExpressCheckoutContainer; |
108 changes: 108 additions & 0 deletions
108
client/tokenized-express-checkout/blocks/components/express-checkout-preview.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { useState } from 'react'; | ||
import { Elements, ExpressCheckoutElement } from '@stripe/react-stripe-js'; | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import InlineNotice from 'components/inline-notice'; | ||
import { getDefaultBorderRadius } from 'wcpay/utils/express-checkout'; | ||
|
||
export const ExpressCheckoutPreviewComponent = ( { | ||
stripe, | ||
buttonType, | ||
theme, | ||
height, | ||
radius, | ||
} ) => { | ||
const [ canRenderButtons, setCanRenderButtons ] = useState( true ); | ||
|
||
const options = { | ||
mode: 'payment', | ||
amount: 1000, | ||
currency: 'usd', | ||
appearance: { | ||
variables: { | ||
borderRadius: `${ radius ?? getDefaultBorderRadius() }px`, | ||
spacingUnit: '6px', | ||
}, | ||
}, | ||
}; | ||
|
||
const mapThemeConfigToButtonTheme = ( paymentMethod, buttonTheme ) => { | ||
switch ( buttonTheme ) { | ||
case 'dark': | ||
return 'black'; | ||
case 'light': | ||
return 'white'; | ||
case 'light-outline': | ||
if ( paymentMethod === 'googlePay' ) { | ||
return 'white'; | ||
} | ||
|
||
return 'white-outline'; | ||
default: | ||
return 'black'; | ||
} | ||
}; | ||
|
||
const type = buttonType === 'default' ? 'plain' : buttonType; | ||
|
||
const buttonOptions = { | ||
buttonHeight: Math.min( Math.max( height, 40 ), 55 ), | ||
buttonTheme: { | ||
googlePay: mapThemeConfigToButtonTheme( 'googlePay', theme ), | ||
applePay: mapThemeConfigToButtonTheme( 'applePay', theme ), | ||
}, | ||
buttonType: { | ||
googlePay: type, | ||
applePay: type, | ||
}, | ||
paymentMethods: { | ||
link: 'never', | ||
googlePay: 'always', | ||
applePay: 'always', | ||
}, | ||
layout: { overflow: 'never' }, | ||
}; | ||
|
||
const onReady = ( { availablePaymentMethods } ) => { | ||
if ( availablePaymentMethods ) { | ||
setCanRenderButtons( true ); | ||
} else { | ||
setCanRenderButtons( false ); | ||
} | ||
}; | ||
|
||
if ( canRenderButtons ) { | ||
return ( | ||
<div | ||
key={ `${ buttonType }-${ theme }` } | ||
style={ { minHeight: `${ height }px`, width: '100%' } } | ||
> | ||
<Elements stripe={ stripe } options={ options }> | ||
<ExpressCheckoutElement | ||
options={ buttonOptions } | ||
onClick={ () => {} } | ||
onReady={ onReady } | ||
/> | ||
</Elements> | ||
</div> | ||
); | ||
} | ||
|
||
return ( | ||
<InlineNotice icon status="error" isDismissible={ false }> | ||
{ __( | ||
'Failed to preview the Apple Pay or Google Pay button. ' + | ||
'Ensure your store uses HTTPS on a publicly available domain ' + | ||
"and you're viewing this page in a Safari or Chrome browser. " + | ||
'Your device must be configured to use Apple Pay or Google Pay.', | ||
'woocommerce-payments' | ||
) } | ||
</InlineNotice> | ||
); | ||
}; |
23 changes: 23 additions & 0 deletions
23
client/tokenized-express-checkout/blocks/express-checkout-element.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Cart Block | ||
.wc-block-components-express-payment--cart { | ||
.wc-block-components-express-payment__event-buttons > li { | ||
padding-bottom: 12px !important; | ||
|
||
&:last-child { | ||
padding-bottom: 0 !important; | ||
} | ||
} | ||
} | ||
|
||
// OR separator | ||
.wc-block-components-express-payment-continue-rule--cart { | ||
margin: 24px 0 !important; | ||
height: 20px; | ||
} | ||
|
||
.wc-block-components-express-payment | ||
.wc-block-components-express-payment__event-buttons | ||
> li { | ||
margin-left: 1px !important; | ||
width: 99% !important; | ||
} |
Oops, something went wrong.