2019-12-12 19:46:56 +00:00
/ * *
* External dependencies
* /
import { _ _ } from '@wordpress/i18n' ;
2020-11-23 13:20:04 +00:00
import { useState , useEffect } from '@wordpress/element' ;
2020-06-25 15:50:48 +00:00
import { PaymentMethodIcons } from '@woocommerce/base-components/cart-checkout' ;
import Button from '@woocommerce/base-components/button' ;
2019-12-12 19:46:56 +00:00
import { CHECKOUT _URL } from '@woocommerce/block-settings' ;
2020-04-02 17:05:08 +00:00
import { useCheckoutContext } from '@woocommerce/base-context' ;
2021-04-08 12:31:12 +00:00
import { usePaymentMethods } from '@woocommerce/base-context/hooks' ;
import { usePositionRelativeToViewport } from '@woocommerce/base-hooks' ;
2020-04-29 10:57:58 +00:00
2019-12-12 19:46:56 +00:00
/ * *
* Internal dependencies
* /
import './style.scss' ;
2020-04-29 10:57:58 +00:00
const getIconsFromPaymentMethods = ( paymentMethods ) => {
return Object . values ( paymentMethods ) . reduce ( ( acc , paymentMethod ) => {
if ( paymentMethod . icons !== null ) {
acc = acc . concat ( paymentMethod . icons ) ;
}
return acc ;
} , [ ] ) ;
} ;
2019-12-12 19:46:56 +00:00
/ * *
* Checkout button rendered in the full cart page .
2020-09-20 23:54:08 +00:00
*
* @ param { Object } props Incoming props for the component .
* @ param { string } props . link What the button is linked to .
2019-12-12 19:46:56 +00:00
* /
2020-03-17 10:30:52 +00:00
const CheckoutButton = ( { link } ) => {
2020-04-02 17:05:08 +00:00
const { isCalculating } = useCheckoutContext ( ) ;
2020-08-20 14:14:12 +00:00
const [
positionReferenceElement ,
positionRelativeToViewport ,
] = usePositionRelativeToViewport ( ) ;
2020-04-15 16:09:15 +00:00
const [ showSpinner , setShowSpinner ] = useState ( false ) ;
2020-04-29 10:57:58 +00:00
const { paymentMethods } = usePaymentMethods ( ) ;
2020-04-02 17:05:08 +00:00
2020-11-23 13:20:04 +00:00
useEffect ( ( ) => {
// Add a listener for when the page is unloaded (specifically needed for Safari)
// to remove the spinner on the checkout button, so the saved page snapshot does not
// contain the spinner class. See https://archive.is/lOEW0 for why this is needed.
if (
! window ||
typeof window . addEventListener !== 'function' ||
typeof window . removeEventListener !== 'function'
) {
return ;
}
const hideSpinner = ( ) => {
setShowSpinner ( false ) ;
} ;
window . addEventListener ( 'beforeunload' , hideSpinner ) ;
return ( ) => {
window . removeEventListener ( 'beforeunload' , hideSpinner ) ;
} ;
} , [ ] ) ;
2020-08-20 14:14:12 +00:00
const submitContainerContents = (
< >
2019-12-12 19:46:56 +00:00
< Button
className = "wc-block-cart__submit-button"
2020-03-17 10:30:52 +00:00
href = { link || CHECKOUT _URL }
2020-04-02 17:05:08 +00:00
disabled = { isCalculating }
2020-04-15 16:09:15 +00:00
onClick = { ( ) => setShowSpinner ( true ) }
showSpinner = { showSpinner }
2019-12-12 19:46:56 +00:00
>
{ _ _ ( 'Proceed to Checkout' , 'woo-gutenberg-products-block' ) }
< / B u t t o n >
2020-04-29 10:57:58 +00:00
< PaymentMethodIcons
icons = { getIconsFromPaymentMethods ( paymentMethods ) }
/ >
2020-08-20 14:14:12 +00:00
< / >
) ;
return (
< div className = "wc-block-cart__submit" >
{ positionReferenceElement }
{ /* The non-sticky container must always be visible because it gives height to its parent, which is required to calculate when it becomes visible in the viewport. */ }
< div className = "wc-block-cart__submit-container" >
{ submitContainerContents }
< / d i v >
{ /* If the positionReferenceElement is below the viewport, display the sticky container. */ }
{ positionRelativeToViewport === 'below' && (
< div className = "wc-block-cart__submit-container wc-block-cart__submit-container--sticky" >
{ submitContainerContents }
< / d i v >
) }
2020-03-10 22:27:52 +00:00
< / d i v >
2019-12-12 19:46:56 +00:00
) ;
} ;
export default CheckoutButton ;