Mini Cart block: add footer (subtotal, cart & checkout buttons and payment method icons) (https://github.com/woocommerce/woocommerce-blocks/pull/4982)
Co-authored-by: Albert Juhé Lluveras <contact@albertjuhe.com>
This commit is contained in:
parent
edaf0f094d
commit
e60405689d
|
@ -42,7 +42,7 @@ $drawer-width-mobile: 100vw;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
transition: opacity $drawer-animation-duration;
|
transition: opacity $drawer-animation-duration;
|
||||||
z-index: 999;
|
z-index: 9999;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import type {
|
||||||
|
PaymentMethods,
|
||||||
|
PaymentMethodIcons as PaymentMethodIconsType,
|
||||||
|
} from '@woocommerce/type-defs/payments';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the provider icons from payment methods data.
|
||||||
|
*
|
||||||
|
* @todo Refactor the Cart blocks to use getIconsFromPaymentMethods utility instead of the local copy.
|
||||||
|
*
|
||||||
|
* @param {PaymentMethods} paymentMethods Payment Method data
|
||||||
|
* @return {PaymentMethodIconsType} Payment Method icons data.
|
||||||
|
*/
|
||||||
|
export const getIconsFromPaymentMethods = (
|
||||||
|
paymentMethods: PaymentMethods
|
||||||
|
): PaymentMethodIconsType => {
|
||||||
|
return Object.values( paymentMethods ).reduce( ( acc, paymentMethod ) => {
|
||||||
|
if ( paymentMethod.icons !== null ) {
|
||||||
|
acc = acc.concat( paymentMethod.icons );
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, [] as PaymentMethodIconsType );
|
||||||
|
};
|
|
@ -7,3 +7,4 @@ export * from './get-valid-block-attributes';
|
||||||
export * from './product-data';
|
export * from './product-data';
|
||||||
export * from './derive-selected-shipping-rates';
|
export * from './derive-selected-shipping-rates';
|
||||||
export * from './from-entries-polyfill';
|
export * from './from-entries-polyfill';
|
||||||
|
export * from './get-icons-from-payment-methods';
|
||||||
|
|
|
@ -4,14 +4,25 @@
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { __, _n, sprintf } from '@wordpress/i18n';
|
import { __, _n, sprintf } from '@wordpress/i18n';
|
||||||
import { useState, useEffect, useRef } from '@wordpress/element';
|
import { useState, useEffect, useRef } from '@wordpress/element';
|
||||||
import { translateJQueryEventToNative } from '@woocommerce/base-utils';
|
import {
|
||||||
import { useStoreCart } from '@woocommerce/base-context/hooks';
|
translateJQueryEventToNative,
|
||||||
|
getIconsFromPaymentMethods,
|
||||||
|
} from '@woocommerce/base-utils';
|
||||||
|
import {
|
||||||
|
useStoreCart,
|
||||||
|
usePaymentMethods,
|
||||||
|
} from '@woocommerce/base-context/hooks';
|
||||||
import Drawer from '@woocommerce/base-components/drawer';
|
import Drawer from '@woocommerce/base-components/drawer';
|
||||||
import {
|
import {
|
||||||
formatPrice,
|
formatPrice,
|
||||||
getCurrencyFromPriceResponse,
|
getCurrencyFromPriceResponse,
|
||||||
} from '@woocommerce/price-format';
|
} from '@woocommerce/price-format';
|
||||||
import { getSetting } from '@woocommerce/settings';
|
import { getSetting } from '@woocommerce/settings';
|
||||||
|
import { TotalsItem } from '@woocommerce/blocks-checkout';
|
||||||
|
import PaymentMethodIcons from '@woocommerce/base-components/cart-checkout/payment-method-icons';
|
||||||
|
import { CART_URL, CHECKOUT_URL } from '@woocommerce/block-settings';
|
||||||
|
import Button from '@woocommerce/base-components/button';
|
||||||
|
import { PaymentMethodDataProvider } from '@woocommerce/base-context';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -23,6 +34,15 @@ interface MiniCartBlockProps {
|
||||||
isInitiallyOpen?: boolean;
|
isInitiallyOpen?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PaymentMethodIconsElement = (): JSX.Element => {
|
||||||
|
const { paymentMethods } = usePaymentMethods();
|
||||||
|
return (
|
||||||
|
<PaymentMethodIcons
|
||||||
|
icons={ getIconsFromPaymentMethods( paymentMethods ) }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const MiniCartBlock = ( {
|
const MiniCartBlock = ( {
|
||||||
isInitiallyOpen = false,
|
isInitiallyOpen = false,
|
||||||
}: MiniCartBlockProps ): JSX.Element => {
|
}: MiniCartBlockProps ): JSX.Element => {
|
||||||
|
@ -80,7 +100,7 @@ const MiniCartBlock = ( {
|
||||||
const subTotal = getSetting( 'displayCartPricesIncludingTax', false )
|
const subTotal = getSetting( 'displayCartPricesIncludingTax', false )
|
||||||
? parseInt( cartTotals.total_items, 10 ) +
|
? parseInt( cartTotals.total_items, 10 ) +
|
||||||
parseInt( cartTotals.total_items_tax, 10 )
|
parseInt( cartTotals.total_items_tax, 10 )
|
||||||
: cartTotals.total_items;
|
: parseInt( cartTotals.total_items, 10 );
|
||||||
|
|
||||||
const ariaLabel = sprintf(
|
const ariaLabel = sprintf(
|
||||||
/* translators: %1$d is the number of products in the cart. %2$s is the cart total */
|
/* translators: %1$d is the number of products in the cart. %2$s is the cart total */
|
||||||
|
@ -104,10 +124,52 @@ const MiniCartBlock = ( {
|
||||||
{ __( 'Cart is empty', 'woo-gutenberg-products-block' ) }
|
{ __( 'Cart is empty', 'woo-gutenberg-products-block' ) }
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="wc-block-mini-cart__items">
|
||||||
<CartLineItemsTable
|
<CartLineItemsTable
|
||||||
lineItems={ cartItems }
|
lineItems={ cartItems }
|
||||||
isLoading={ cartIsLoading }
|
isLoading={ cartIsLoading }
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="wc-block-mini-cart__footer">
|
||||||
|
<TotalsItem
|
||||||
|
className="wc-block-mini-cart__footer-subtotal"
|
||||||
|
currency={ getCurrencyFromPriceResponse( cartTotals ) }
|
||||||
|
label={ __(
|
||||||
|
'Subtotal',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
value={ subTotal }
|
||||||
|
description={ __(
|
||||||
|
'Shipping, taxes, and discounts calculated at checkout.',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
/>
|
||||||
|
<div className="wc-block-mini-cart__footer-actions">
|
||||||
|
<Button
|
||||||
|
className="wc-block-mini-cart__footer-cart"
|
||||||
|
href={ CART_URL }
|
||||||
|
>
|
||||||
|
{ __(
|
||||||
|
'View my cart',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="wc-block-mini-cart__footer-checkout"
|
||||||
|
href={ CHECKOUT_URL }
|
||||||
|
>
|
||||||
|
{ __(
|
||||||
|
'Go to checkout',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<PaymentMethodDataProvider>
|
||||||
|
<PaymentMethodIconsElement />
|
||||||
|
</PaymentMethodDataProvider>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -5,4 +5,77 @@
|
||||||
// Reset font size so it doesn't depend on drawer's ancestors.
|
// Reset font size so it doesn't depend on drawer's ancestors.
|
||||||
.wc-block-mini-cart__drawer {
|
.wc-block-mini-cart__drawer {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
|
|
||||||
|
.components-modal__content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.components-modal__header {
|
||||||
|
margin: $gap 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-mini-cart__items {
|
||||||
|
flex-grow: 1;
|
||||||
|
margin-right: -$gap;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: $gap;
|
||||||
|
|
||||||
|
.wc-block-cart-items__row:last-child::after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-mini-cart__footer {
|
||||||
|
border-top: 1px solid $gray-300;
|
||||||
|
margin-bottom: -$gap-largest;
|
||||||
|
margin-left: -$gap;
|
||||||
|
margin-right: -$gap;
|
||||||
|
padding: $gap-large;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-components-totals-item.wc-block-mini-cart__footer-subtotal {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: $gap;
|
||||||
|
|
||||||
|
.wc-block-components-totals-item__description {
|
||||||
|
display: none;
|
||||||
|
font-size: 0.75em;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
@media only screen and (min-width: 480px) {
|
||||||
|
display: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-mini-cart__footer-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: $gap;
|
||||||
|
|
||||||
|
.wc-block-mini-cart__footer-cart.wc-block-components-button {
|
||||||
|
background-color: transparent;
|
||||||
|
border: 1px solid $gray-900;
|
||||||
|
color: $gray-900;
|
||||||
|
display: none;
|
||||||
|
flex-grow: 1;
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
@media only screen and (min-width: 480px) {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-mini-cart__footer-checkout {
|
||||||
|
border: 1px solid $gray-900;
|
||||||
|
flex-grow: 1;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-block-mini-cart__footer .wc-block-components-payment-method-icons {
|
||||||
|
margin-top: $gap;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use Automattic\WooCommerce\Blocks\Package;
|
||||||
use Automattic\WooCommerce\Blocks\Assets;
|
use Automattic\WooCommerce\Blocks\Assets;
|
||||||
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
|
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
|
||||||
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\CartController;
|
use Automattic\WooCommerce\Blocks\StoreApi\Utilities\CartController;
|
||||||
|
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mini Cart class.
|
* Mini Cart class.
|
||||||
|
@ -96,6 +97,14 @@ class MiniCart extends AbstractBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$payment_method_registry = Package::container()->get( PaymentMethodRegistry::class );
|
||||||
|
$payment_methods = $payment_method_registry->get_all_active_payment_method_script_dependencies();
|
||||||
|
|
||||||
|
foreach ( $payment_methods as $payment_method ) {
|
||||||
|
$payment_method_script = $this->get_script_from_handle( $payment_method );
|
||||||
|
$this->append_script_and_deps_src( $payment_method_script );
|
||||||
|
}
|
||||||
|
|
||||||
$this->scripts_to_lazy_load['wc-block-mini-cart-component-frontend'] = array(
|
$this->scripts_to_lazy_load['wc-block-mini-cart-component-frontend'] = array(
|
||||||
'src' => $script_data['src'],
|
'src' => $script_data['src'],
|
||||||
'version' => $script_data['version'],
|
'version' => $script_data['version'],
|
||||||
|
@ -165,6 +174,9 @@ class MiniCart extends AbstractBlock {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( ! $script->src ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$this->scripts_to_lazy_load[ $script->handle ] = array(
|
$this->scripts_to_lazy_load[ $script->handle ] = array(
|
||||||
'src' => $script->src,
|
'src' => $script->src,
|
||||||
'version' => $script->ver,
|
'version' => $script->ver,
|
||||||
|
|
Loading…
Reference in New Issue