Add Order Summary card to Checkout sidebar (https://github.com/woocommerce/woocommerce-blocks/pull/1959)
* Add missing props to sidebar-layout components * Move specific CSS class to checkout block * Add comment on top of @wordpress/components styles in webpack entry * Make it so our styles load after vendor styles * Remove unnecessary @todo comment * Add Order Summary card to Checkout sidebar * Improve responsive layout * Increase cart.js bundlewatch size * Remove wrong comment * Remove unnecessary usage of useStoreCartItemQuantity * Refactor layout so the product description can occupy more width * Move paddings to the button so focus styles look better
This commit is contained in:
parent
bef5514044
commit
5d1d8f0394
|
@ -1 +1,8 @@
|
|||
export { default as Button } from './button';
|
||||
export { default as ProductImage } from './product-image';
|
||||
export { default as ProductLowStockBadge } from './product-low-stock-badge';
|
||||
export { default as ProductMetadata } from './product-metadata';
|
||||
export { default as ProductName } from './product-name';
|
||||
export { default as ProductPrice } from './product-price';
|
||||
export { default as ProductSaleBadge } from './product-sale-badge';
|
||||
export { default as ProductVariationData } from './product-variation-data';
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { decodeEntities } from '@wordpress/html-entities';
|
||||
import { PLACEHOLDER_IMG_SRC } from '@woocommerce/block-settings';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Formats and returns an image element.
|
||||
*/
|
||||
const ProductImage = ( { image = {} } ) => {
|
||||
const imageProps = {
|
||||
src: image.src || PLACEHOLDER_IMG_SRC,
|
||||
alt: decodeEntities( image.alt ) || '',
|
||||
srcSet: image.srcset || '',
|
||||
sizes: image.sizes || '',
|
||||
};
|
||||
|
||||
return <img { ...imageProps } alt={ imageProps.alt } />;
|
||||
};
|
||||
|
||||
ProductImage.propTypes = {
|
||||
image: PropTypes.shape( {
|
||||
alt: PropTypes.string,
|
||||
src: PropTypes.string,
|
||||
srcsizes: PropTypes.string,
|
||||
srcset: PropTypes.string,
|
||||
} ),
|
||||
};
|
||||
|
||||
export default ProductImage;
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import './style.scss';
|
||||
|
||||
/**
|
||||
* Returns a low stock badge.
|
||||
*/
|
||||
const ProductLowStockBadge = ( { lowStockRemaining } ) => {
|
||||
if ( ! lowStockRemaining ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="wc-block-low-stock-badge">
|
||||
{ sprintf(
|
||||
/* translators: %d stock amount (number of items in stock for product) */
|
||||
__( '%d left in stock', 'woo-gutenberg-products-block' ),
|
||||
lowStockRemaining
|
||||
) }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ProductLowStockBadge.propTypes = {
|
||||
lowStockRemaining: PropTypes.number,
|
||||
};
|
||||
|
||||
export default ProductLowStockBadge;
|
|
@ -0,0 +1,11 @@
|
|||
.wc-block-low-stock-badge {
|
||||
background-color: $white;
|
||||
border-radius: 3px;
|
||||
border: 1px solid $black;
|
||||
display: inline-block;
|
||||
color: $black;
|
||||
font-size: 12px;
|
||||
padding: 0 1em;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { RawHTML } from '@wordpress/element';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import ProductVariationData from '../product-variation-data';
|
||||
import './style.scss';
|
||||
|
||||
const ProductMetadata = ( { summary, variation } ) => {
|
||||
return (
|
||||
<div className="wc-block-product-metadata">
|
||||
{ summary && <RawHTML>{ summary }</RawHTML> }
|
||||
{ variation && <ProductVariationData variation={ variation } /> }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ProductMetadata.propTypes = {
|
||||
summary: PropTypes.string,
|
||||
variation: PropTypes.array,
|
||||
};
|
||||
|
||||
export default ProductMetadata;
|
|
@ -0,0 +1,5 @@
|
|||
.wc-block-product-metadata {
|
||||
color: $core-grey-dark-400;
|
||||
font-size: 12px;
|
||||
margin-top: 0.25em;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import './style.scss';
|
||||
|
||||
const ProductName = ( { name, permalink } ) => {
|
||||
return (
|
||||
<a className="wc-block-product-name" href={ permalink }>
|
||||
{ name }
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
ProductName.propTypes = {
|
||||
name: PropTypes.string,
|
||||
permalink: PropTypes.string,
|
||||
};
|
||||
|
||||
export default ProductName;
|
|
@ -0,0 +1,5 @@
|
|||
.wc-block-product-name {
|
||||
color: $core-grey-dark-600;
|
||||
font-size: 16px;
|
||||
display: block;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-monetary-amount';
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import './style.scss';
|
||||
|
||||
const ProductPrice = ( { className, currency, regularValue, value } ) => {
|
||||
return (
|
||||
<>
|
||||
{ Number.isFinite( regularValue ) && regularValue !== value && (
|
||||
<FormattedMonetaryAmount
|
||||
className={ classNames(
|
||||
'wc-block-product-price--regular',
|
||||
className
|
||||
) }
|
||||
currency={ currency }
|
||||
value={ regularValue }
|
||||
/>
|
||||
) }
|
||||
<FormattedMonetaryAmount
|
||||
className={ classNames( 'wc-block-product-price', className ) }
|
||||
currency={ currency }
|
||||
value={ value }
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
ProductPrice.propTypes = {
|
||||
currency: PropTypes.object.isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
className: PropTypes.string,
|
||||
regularValue: PropTypes.number,
|
||||
};
|
||||
|
||||
export default ProductPrice;
|
|
@ -0,0 +1,12 @@
|
|||
.wc-block-product-price {
|
||||
color: $black;
|
||||
}
|
||||
|
||||
.wc-block-product-price--regular {
|
||||
color: $core-grey-dark-400;
|
||||
text-decoration: line-through;
|
||||
|
||||
+ .wc-block-product-price {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { formatPrice } from '@woocommerce/base-utils';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import './style.scss';
|
||||
|
||||
const ProductSaleBadge = ( { currency, saleAmount } ) => {
|
||||
return (
|
||||
saleAmount > 0 && (
|
||||
<div className="wc-block-sale-badge">
|
||||
{ sprintf(
|
||||
/* translators: %s discount amount */
|
||||
__( 'Save %s!', 'woo-gutenberg-products-block' ),
|
||||
formatPrice( saleAmount, currency )
|
||||
) }
|
||||
</div>
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
ProductSaleBadge.propTypes = {
|
||||
currency: PropTypes.object,
|
||||
saleAmount: PropTypes.number,
|
||||
};
|
||||
|
||||
export default ProductSaleBadge;
|
|
@ -0,0 +1,10 @@
|
|||
.wc-block-sale-badge {
|
||||
background-color: $core-grey-dark-600;
|
||||
border-radius: 3px;
|
||||
color: $white;
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
padding: 0 1em;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { decodeEntities } from '@wordpress/html-entities';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Returns a formatted element containing variation details.
|
||||
*/
|
||||
const ProductVariationData = ( { variation } ) => {
|
||||
const variationsText = variation
|
||||
.map( ( v ) => {
|
||||
if ( v.attribute ) {
|
||||
return `${ decodeEntities( v.attribute ) }: ${ decodeEntities(
|
||||
v.value
|
||||
) }`;
|
||||
}
|
||||
// Support for product attributes with no name/key
|
||||
return `${ decodeEntities( v.value ) }`;
|
||||
} )
|
||||
.join( ' / ' );
|
||||
|
||||
return (
|
||||
<div className="wc-block-product-variation-data">
|
||||
{ variationsText }
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ProductVariationData.propTypes = {
|
||||
variation: PropTypes.arrayOf(
|
||||
PropTypes.shape( {
|
||||
attribute: PropTypes.string,
|
||||
value: PropTypes.string.isRequired,
|
||||
} )
|
||||
),
|
||||
};
|
||||
|
||||
export default ProductVariationData;
|
|
@ -1,7 +1,3 @@
|
|||
.wc-block-shipping-rates-control__package:not(:first-of-type) {
|
||||
margin-top: $gap-larger;
|
||||
}
|
||||
|
||||
.wc-block-shipping-rates-control__package-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Main = ( { children, className } ) => {
|
||||
return (
|
||||
|
@ -11,4 +12,8 @@ const Main = ( { children, className } ) => {
|
|||
);
|
||||
};
|
||||
|
||||
Main.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Main;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const SidebarLayout = ( { children, className } ) => {
|
||||
return (
|
||||
|
@ -11,4 +12,8 @@ const SidebarLayout = ( { children, className } ) => {
|
|||
);
|
||||
};
|
||||
|
||||
SidebarLayout.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default SidebarLayout;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Sidebar = ( { children, className } ) => {
|
||||
return (
|
||||
|
@ -11,4 +12,8 @@ const Sidebar = ( { children, className } ) => {
|
|||
);
|
||||
};
|
||||
|
||||
Sidebar.propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Sidebar;
|
||||
|
|
|
@ -9,49 +9,49 @@
|
|||
padding: 0 $gap;
|
||||
min-width: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-block-sidebar {
|
||||
flex: 1 1 35%;
|
||||
margin: 0;
|
||||
max-width: 35%;
|
||||
padding: 0 $gap;
|
||||
.wc-block-sidebar {
|
||||
flex: 1 1 35%;
|
||||
margin: 0;
|
||||
max-width: 35%;
|
||||
padding: 0 $gap;
|
||||
|
||||
// Reset Gutenberg <Panel> styles when used in the sidebar.
|
||||
.components-panel__body {
|
||||
border-top: 1px solid $core-grey-light-600;
|
||||
border-bottom: 1px solid $core-grey-light-600;
|
||||
// Reset Gutenberg <Panel> styles when used in the sidebar.
|
||||
.components-panel__body {
|
||||
border-top: 1px solid $core-grey-light-600;
|
||||
border-bottom: 1px solid $core-grey-light-600;
|
||||
|
||||
&.is-opened {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
&.is-opened {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
|
||||
> .components-panel__body-title {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
> .components-panel__body-title {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .components-panel__body-title,
|
||||
.components-panel__body-toggle {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
> .components-panel__body-title,
|
||||
.components-panel__body-toggle {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.components-panel__body-toggle {
|
||||
font-weight: normal;
|
||||
font-size: inherit;
|
||||
padding-left: 0;
|
||||
padding-right: 36px;
|
||||
.components-panel__body-toggle {
|
||||
font-weight: normal;
|
||||
font-size: inherit;
|
||||
padding-left: 0;
|
||||
padding-right: 36px;
|
||||
|
||||
&.components-button,
|
||||
&.components-button:focus:not(:disabled):not([aria-disabled="true"]) {
|
||||
color: inherit;
|
||||
}
|
||||
&.components-button,
|
||||
&.components-button:focus:not(:disabled):not([aria-disabled="true"]) {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { RawHTML } from '@wordpress/element';
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
import QuantitySelector from '@woocommerce/base-components/quantity-selector';
|
||||
import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-monetary-amount';
|
||||
import { getCurrency, formatPrice } from '@woocommerce/base-utils';
|
||||
import { getCurrency } from '@woocommerce/base-utils';
|
||||
import { useStoreCartItemQuantity } from '@woocommerce/base-hooks';
|
||||
import { Icon, trash } from '@woocommerce/icons';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import ProductVariationData from './product-variation-data';
|
||||
import ProductImage from './product-image';
|
||||
import ProductLowStockBadge from './product-low-stock-badge';
|
||||
import {
|
||||
ProductImage,
|
||||
ProductLowStockBadge,
|
||||
ProductMetadata,
|
||||
ProductName,
|
||||
ProductPrice,
|
||||
ProductSaleBadge,
|
||||
} from '@woocommerce/base-components/cart-checkout';
|
||||
|
||||
/**
|
||||
* @typedef {import('@woocommerce/type-defs/cart').CartItem} CartItem
|
||||
|
@ -73,17 +72,9 @@ const CartLineItemRow = ( { lineItem } ) => {
|
|||
</a>
|
||||
</td>
|
||||
<td className="wc-block-cart-item__product">
|
||||
<a
|
||||
className="wc-block-cart-item__product-name"
|
||||
href={ permalink }
|
||||
>
|
||||
{ name }
|
||||
</a>
|
||||
<ProductName permalink={ permalink } name={ name } />
|
||||
<ProductLowStockBadge lowStockRemaining={ lowStockRemaining } />
|
||||
<div className="wc-block-cart-item__product-metadata">
|
||||
<RawHTML>{ summary }</RawHTML>
|
||||
<ProductVariationData variation={ variation } />
|
||||
</div>
|
||||
<ProductMetadata summary={ summary } variation={ variation } />
|
||||
</td>
|
||||
<td className="wc-block-cart-item__quantity">
|
||||
<QuantitySelector
|
||||
|
@ -112,27 +103,15 @@ const CartLineItemRow = ( { lineItem } ) => {
|
|||
</button>
|
||||
</td>
|
||||
<td className="wc-block-cart-item__total">
|
||||
{ saleAmount > 0 && (
|
||||
<FormattedMonetaryAmount
|
||||
className="wc-block-cart-item__regular-price"
|
||||
currency={ currency }
|
||||
value={ regularPrice }
|
||||
/>
|
||||
) }
|
||||
<FormattedMonetaryAmount
|
||||
className="wc-block-cart-item__price"
|
||||
<ProductPrice
|
||||
currency={ currency }
|
||||
regularValue={ regularPrice }
|
||||
value={ purchasePrice }
|
||||
/>
|
||||
{ saleAmount > 0 && (
|
||||
<div className="wc-block-cart-item__sale-badge">
|
||||
{ sprintf(
|
||||
/* translators: %s discount amount */
|
||||
__( 'Save %s!', 'woo-gutenberg-products-block' ),
|
||||
formatPrice( saleAmount, currency )
|
||||
) }
|
||||
</div>
|
||||
) }
|
||||
<ProductSaleBadge
|
||||
currency={ currency }
|
||||
saleAmount={ saleAmount }
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
|
|
@ -113,32 +113,6 @@ table.wc-block-cart-items {
|
|||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
.wc-block-cart-item__product {
|
||||
.wc-block-cart-item__product-name {
|
||||
color: $core-grey-dark-600;
|
||||
font-size: 16px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.wc-block-cart-item__low-stock-badge {
|
||||
display: inline-block;
|
||||
|
||||
background-color: $white;
|
||||
border-radius: 3px;
|
||||
border: 1px solid $black;
|
||||
color: $black;
|
||||
font-size: 12px;
|
||||
padding: 0 1em;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wc-block-cart-item__product-metadata {
|
||||
color: $core-grey-dark-400;
|
||||
font-size: 12px;
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
}
|
||||
.wc-block-cart-item__quantity {
|
||||
.wc-block-cart-item__remove-link {
|
||||
@include link-button;
|
||||
|
@ -172,27 +146,6 @@ table.wc-block-cart-items {
|
|||
.wc-block-formatted-money-amount {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.wc-block-cart-item__regular-price {
|
||||
color: $core-grey-dark-400;
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.wc-block-cart-item__price {
|
||||
color: $black;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.wc-block-cart-item__sale-badge {
|
||||
background-color: $core-grey-dark-600;
|
||||
border-radius: 3px;
|
||||
color: $white;
|
||||
font-size: 12px;
|
||||
padding: 0 1em;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,20 +164,19 @@ table.wc-block-cart-items {
|
|||
}
|
||||
.wc-block-cart-items {
|
||||
.wc-block-cart-items__row {
|
||||
.wc-block-cart-item__product-name,
|
||||
.wc-block-cart-item__price,
|
||||
.wc-block-cart-item__product-metadata,
|
||||
.wc-block-product-price,
|
||||
.wc-block-product-metadata,
|
||||
.wc-block-cart-item__image > *,
|
||||
.wc-block-quantity-selector {
|
||||
@include placeholder();
|
||||
}
|
||||
.wc-block-cart-item__product-name {
|
||||
.wc-block-product-name {
|
||||
@include placeholder();
|
||||
@include force-content();
|
||||
min-width: 84px;
|
||||
display: inline-block;
|
||||
}
|
||||
.wc-block-cart-item__product-metadata {
|
||||
.wc-block-product-metadata {
|
||||
margin-top: 0.25em;
|
||||
min-width: 8em;
|
||||
}
|
||||
|
@ -240,7 +192,7 @@ table.wc-block-cart-items {
|
|||
> div {
|
||||
display: none;
|
||||
}
|
||||
.wc-block-cart-item__price {
|
||||
.wc-block-product-price {
|
||||
@include force-content();
|
||||
display: block;
|
||||
}
|
||||
|
@ -321,7 +273,7 @@ table.wc-block-cart-items {
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
.wc-block-cart-item__sale-badge {
|
||||
.wc-block-sale-badge {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import {
|
|||
Sidebar,
|
||||
SidebarLayout,
|
||||
Main,
|
||||
} from '@woocommerce/base-components/sidebar-layout'; // @todo
|
||||
} from '@woocommerce/base-components/sidebar-layout';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -40,6 +40,7 @@ import '../../../payment-methods-demo';
|
|||
const Block = ( {
|
||||
attributes,
|
||||
cartCoupons = [],
|
||||
cartItems = [],
|
||||
cartTotals = {},
|
||||
isEditor = false,
|
||||
shippingRates = [],
|
||||
|
@ -326,9 +327,10 @@ const Block = ( {
|
|||
{ attributes.showPolicyLinks && <Policies /> }
|
||||
</CheckoutForm>
|
||||
</Main>
|
||||
<Sidebar>
|
||||
<Sidebar className="wc-block-checkout__sidebar">
|
||||
<CheckoutSidebar
|
||||
cartCoupons={ cartCoupons }
|
||||
cartItems={ cartItems }
|
||||
cartTotals={ cartTotals }
|
||||
shippingRates={ shippingRates }
|
||||
/>
|
||||
|
|
|
@ -219,6 +219,7 @@ const CheckoutEditor = ( { attributes, setAttributes } ) => {
|
|||
>
|
||||
<Block
|
||||
attributes={ attributes }
|
||||
cartItems={ previewCart.items }
|
||||
cartTotals={ previewCart.totals }
|
||||
isEditor={ true }
|
||||
shippingRates={
|
||||
|
|
|
@ -26,6 +26,7 @@ import renderFrontend from '../../../utils/render-frontend.js';
|
|||
const CheckoutFrontend = ( props ) => {
|
||||
const {
|
||||
cartCoupons,
|
||||
cartItems,
|
||||
cartErrors,
|
||||
cartTotals,
|
||||
shippingRates,
|
||||
|
@ -58,6 +59,7 @@ const CheckoutFrontend = ( props ) => {
|
|||
<Block
|
||||
{ ...props }
|
||||
cartCoupons={ cartCoupons }
|
||||
cartItems={ cartItems }
|
||||
cartTotals={ cartTotals }
|
||||
shippingRates={ shippingRates }
|
||||
/>
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { getCurrency } from '@woocommerce/base-utils';
|
||||
import Label from '@woocommerce/base-components/label';
|
||||
import {
|
||||
ProductImage,
|
||||
ProductLowStockBadge,
|
||||
ProductMetadata,
|
||||
ProductName,
|
||||
ProductPrice,
|
||||
} from '@woocommerce/base-components/cart-checkout';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const CheckoutOrderSummaryItem = ( { cartItem } ) => {
|
||||
const {
|
||||
images,
|
||||
low_stock_remaining: lowStockRemaining = null,
|
||||
name,
|
||||
permalink,
|
||||
prices,
|
||||
quantity,
|
||||
summary,
|
||||
variation,
|
||||
} = cartItem;
|
||||
|
||||
const currency = getCurrency( prices );
|
||||
const regularPrice = parseInt( prices.regular_price, 10 );
|
||||
const purchasePrice = parseInt( prices.price, 10 );
|
||||
|
||||
return (
|
||||
<div className="wc-block-order-summary-item">
|
||||
<div className="wc-block-order-summary-item__image">
|
||||
<ProductImage image={ images.length ? images[ 0 ] : {} } />
|
||||
<div className="wc-block-order-summary-item__quantity">
|
||||
<Label
|
||||
label={ quantity }
|
||||
screenReaderLabel={ sprintf(
|
||||
/* translators: %d number of products of the same type in the cart */
|
||||
__( '%d items', 'woo-gutenberg-products-block' ),
|
||||
quantity
|
||||
) }
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="wc-block-order-summary-item__description">
|
||||
<div className="wc-block-order-summary-item__header">
|
||||
<ProductPrice
|
||||
className="wc-block-order-summary-item__total-price"
|
||||
currency={ currency }
|
||||
value={ purchasePrice * quantity }
|
||||
/>
|
||||
<ProductName permalink={ permalink } name={ name } />
|
||||
</div>
|
||||
<div className="wc-block-order-summary-item__prices">
|
||||
<ProductPrice
|
||||
currency={ currency }
|
||||
regularValue={ regularPrice }
|
||||
value={ purchasePrice }
|
||||
/>
|
||||
</div>
|
||||
<ProductLowStockBadge lowStockRemaining={ lowStockRemaining } />
|
||||
<ProductMetadata summary={ summary } variation={ variation } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CheckoutOrderSummaryItem.propTypes = {
|
||||
cartItems: PropTypes.shape( {
|
||||
images: PropTypes.array,
|
||||
low_stock_remaining: PropTypes.number,
|
||||
name: PropTypes.string.isRequired,
|
||||
permalink: PropTypes.string,
|
||||
prices: PropTypes.shape( {
|
||||
price: PropTypes.string,
|
||||
regular_price: PropTypes.string,
|
||||
} ),
|
||||
quantity: PropTypes.number,
|
||||
summary: PropTypes.string,
|
||||
variation: PropTypes.array,
|
||||
} ),
|
||||
};
|
||||
|
||||
export default CheckoutOrderSummaryItem;
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Card, CardBody, PanelBody, PanelRow } from 'wordpress-components';
|
||||
import { Icon, cart } from '@woocommerce/icons';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import CheckoutOrderSummaryItem from './order-summary-item.js';
|
||||
|
||||
const CheckoutOrderSummary = ( { cartItems = [] } ) => {
|
||||
return (
|
||||
<Card isElevated={ true }>
|
||||
<CardBody>
|
||||
<PanelBody
|
||||
className="wc-block-order-summary"
|
||||
title={
|
||||
<>
|
||||
<Icon
|
||||
className="wc-block-order-summary__button-icon"
|
||||
srcElement={ cart }
|
||||
/>
|
||||
<span className="wc-block-order-summary__button-text">
|
||||
{ __(
|
||||
'Order summary',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
initialOpen={ true }
|
||||
>
|
||||
<PanelRow className="wc-block-order-summary__row">
|
||||
{ cartItems.map( ( cartItem ) => {
|
||||
return (
|
||||
<CheckoutOrderSummaryItem
|
||||
key={ cartItem.key }
|
||||
cartItem={ cartItem }
|
||||
/>
|
||||
);
|
||||
} ) }
|
||||
</PanelRow>
|
||||
</PanelBody>
|
||||
</CardBody>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
CheckoutOrderSummary.propTypes = {
|
||||
cartItems: PropTypes.arrayOf(
|
||||
PropTypes.shape( { key: PropTypes.string.isRequired } )
|
||||
),
|
||||
};
|
||||
|
||||
export default CheckoutOrderSummary;
|
|
@ -17,8 +17,14 @@ import {
|
|||
} from '@woocommerce/block-settings';
|
||||
import { useStoreCartCoupons } from '@woocommerce/base-hooks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import OrderSummary from './order-summary.js';
|
||||
|
||||
const CheckoutSidebar = ( {
|
||||
cartCoupons = [],
|
||||
cartItems = [],
|
||||
cartTotals = {},
|
||||
shippingRates,
|
||||
} ) => {
|
||||
|
@ -33,6 +39,7 @@ const CheckoutSidebar = ( {
|
|||
|
||||
return (
|
||||
<>
|
||||
<OrderSummary cartItems={ cartItems } />
|
||||
<SubtotalsItem currency={ totalsCurrency } values={ cartTotals } />
|
||||
<TotalsFeesItem currency={ totalsCurrency } values={ cartTotals } />
|
||||
<TotalsDiscountItem
|
||||
|
|
|
@ -4,6 +4,85 @@
|
|||
margin-top: $gap;
|
||||
}
|
||||
|
||||
.wc-block-checkout .wc-block-shipping-rates-control__package:not(:first-of-type) {
|
||||
margin-top: $gap-larger;
|
||||
}
|
||||
|
||||
.wc-block-checkout__sidebar {
|
||||
.wc-block-order-summary {
|
||||
border: none;
|
||||
|
||||
> .components-panel__body-title > .components-panel__body-toggle {
|
||||
padding: $gap-small 0;
|
||||
}
|
||||
|
||||
.components-panel__body-toggle {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-block-order-summary__button-icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.wc-block-order-summary__button-text {
|
||||
margin-left: $gap;
|
||||
}
|
||||
|
||||
.wc-block-order-summary__row {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wc-block-order-summary-item {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.wc-block-order-summary-item__image,
|
||||
.wc-block-order-summary-item__description,
|
||||
.wc-block-order-summary-item__total-price {
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.wc-block-order-summary-item__image {
|
||||
width: 48px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wc-block-order-summary-item__quantity {
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
border: 2px solid currentColor;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
font-size: 11px;
|
||||
min-height: 22px;
|
||||
position: absolute;
|
||||
justify-content: center;
|
||||
right: -6px;
|
||||
top: -6px;
|
||||
min-width: 22px;
|
||||
}
|
||||
|
||||
.wc-block-order-summary-item__description {
|
||||
padding-left: $gap-small;
|
||||
padding-right: $gap-small;
|
||||
}
|
||||
|
||||
.wc-block-product-name {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.wc-block-order-summary-item__prices {
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
.wc-block-order-summary-item__total-price {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint( ">480px" ) {
|
||||
.wc-block-checkout__billing-fields,
|
||||
.wc-block-checkout__shipping-fields {
|
||||
|
@ -37,4 +116,38 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wc-block-checkout__sidebar {
|
||||
.wc-block-totals-table-item {
|
||||
padding-left: $gap-small;
|
||||
padding-right: $gap-small;
|
||||
}
|
||||
|
||||
.wc-block-coupon-code .components-panel__body-toggle {
|
||||
padding-left: $gap-small;
|
||||
}
|
||||
|
||||
.wc-block-coupon-code__row {
|
||||
padding-left: $gap-small;
|
||||
padding-right: $gap-small;
|
||||
}
|
||||
|
||||
.wc-block-order-summary {
|
||||
> .components-panel__body-title > .components-panel__body-toggle {
|
||||
padding-left: $gap-small;
|
||||
}
|
||||
}
|
||||
|
||||
.wc-block-order-summary__row {
|
||||
padding: 0 $gap-small;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint( ">782px" ) {
|
||||
.wc-block-checkout__sidebar {
|
||||
.wc-block-order-summary {
|
||||
margin: -20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,15 @@ const stableMainEntry = {
|
|||
// Shared blocks code
|
||||
blocks: './assets/js/index.js',
|
||||
|
||||
// @wordpress/components styles
|
||||
'panel-style': './node_modules/@wordpress/components/src/panel/style.scss',
|
||||
'custom-select-control-style':
|
||||
'./node_modules/@wordpress/components/src/custom-select-control/style.scss',
|
||||
'checkbox-control-style':
|
||||
'./node_modules/@wordpress/components/src/checkbox-control/style.scss',
|
||||
'spinner-style':
|
||||
'./node_modules/@wordpress/components/src/spinner/style.scss',
|
||||
|
||||
// Blocks
|
||||
'handpicked-products': './assets/js/blocks/handpicked-products/index.js',
|
||||
'product-best-sellers': './assets/js/blocks/product-best-sellers/index.js',
|
||||
|
@ -129,13 +138,6 @@ const stableMainEntry = {
|
|||
'active-filters': './assets/js/blocks/active-filters/index.js',
|
||||
'block-error-boundary':
|
||||
'./assets/js/base/components/block-error-boundary/style.scss',
|
||||
'panel-style': './node_modules/@wordpress/components/src/panel/style.scss',
|
||||
'custom-select-control-style':
|
||||
'./node_modules/@wordpress/components/src/custom-select-control/style.scss',
|
||||
'checkbox-control-style':
|
||||
'./node_modules/@wordpress/components/src/checkbox-control/style.scss',
|
||||
'spinner-style':
|
||||
'./node_modules/@wordpress/components/src/spinner/style.scss',
|
||||
};
|
||||
|
||||
const experimentalMainEntry = {
|
||||
|
|
|
@ -174,7 +174,7 @@
|
|||
},
|
||||
{
|
||||
"path": "./build/cart.js",
|
||||
"maxSize": "70 kB"
|
||||
"maxSize": "80 kB"
|
||||
},
|
||||
{
|
||||
"path": "./build/cart-frontend.js",
|
||||
|
|
|
@ -35,10 +35,10 @@ class Assets {
|
|||
* as part of ongoing refactoring.
|
||||
*/
|
||||
public static function register_assets() {
|
||||
self::register_style( 'wc-block-vendors-style', plugins_url( self::get_block_asset_build_path( 'vendors-style', 'css' ), __DIR__ ), [] );
|
||||
self::register_style( 'wc-block-editor', plugins_url( self::get_block_asset_build_path( 'editor', 'css' ), __DIR__ ), array( 'wp-edit-blocks' ) );
|
||||
wp_style_add_data( 'wc-block-editor', 'rtl', 'replace' );
|
||||
self::register_style( 'wc-block-style', plugins_url( self::get_block_asset_build_path( 'style', 'css' ), __DIR__ ), [] );
|
||||
self::register_style( 'wc-block-vendors-style', plugins_url( self::get_block_asset_build_path( 'vendors-style', 'css' ), __DIR__ ), [] );
|
||||
self::register_style( 'wc-block-style', plugins_url( self::get_block_asset_build_path( 'style', 'css' ), __DIR__ ), array( 'wc-block-vendors-style' ) );
|
||||
wp_style_add_data( 'wc-block-style', 'rtl', 'replace' );
|
||||
|
||||
// Shared libraries and components across all blocks.
|
||||
|
|
Loading…
Reference in New Issue