Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Add Order Summary card to Checkout sidebar (#1959)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Aljullu authored Mar 13, 2020
1 parent 2f04157 commit 746e5b7
Show file tree
Hide file tree
Showing 30 changed files with 636 additions and 143 deletions.
7 changes: 7 additions & 0 deletions assets/js/base/components/cart-checkout/index.js
Original file line number Diff line number Diff line change
@@ -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';
31 changes: 31 additions & 0 deletions assets/js/base/components/cart-checkout/product-image/index.js
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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;
}
27 changes: 27 additions & 0 deletions assets/js/base/components/cart-checkout/product-metadata/index.js
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.wc-block-product-metadata {
color: $core-grey-dark-400;
font-size: 12px;
margin-top: 0.25em;
}
24 changes: 24 additions & 0 deletions assets/js/base/components/cart-checkout/product-name/index.js
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.wc-block-product-name {
color: $core-grey-dark-600;
font-size: 16px;
display: block;
}
42 changes: 42 additions & 0 deletions assets/js/base/components/cart-checkout/product-price/index.js
Original file line number Diff line number Diff line change
@@ -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;
12 changes: 12 additions & 0 deletions assets/js/base/components/cart-checkout/product-price/style.scss
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
4 changes: 0 additions & 4 deletions assets/js/base/components/shipping-rates-control/style.scss
Original file line number Diff line number Diff line change
@@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions assets/js/base/components/sidebar-layout/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import classNames from 'classnames';
import PropTypes from 'prop-types';

const Main = ( { children, className } ) => {
return (
Expand All @@ -11,4 +12,8 @@ const Main = ( { children, className } ) => {
);
};

Main.propTypes = {
className: PropTypes.string,
};

export default Main;
5 changes: 5 additions & 0 deletions assets/js/base/components/sidebar-layout/sidebar-layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import classNames from 'classnames';
import PropTypes from 'prop-types';

const SidebarLayout = ( { children, className } ) => {
return (
Expand All @@ -11,4 +12,8 @@ const SidebarLayout = ( { children, className } ) => {
);
};

SidebarLayout.propTypes = {
className: PropTypes.string,
};

export default SidebarLayout;
5 changes: 5 additions & 0 deletions assets/js/base/components/sidebar-layout/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import classNames from 'classnames';
import PropTypes from 'prop-types';

const Sidebar = ( { children, className } ) => {
return (
Expand All @@ -11,4 +12,8 @@ const Sidebar = ( { children, className } ) => {
);
};

Sidebar.propTypes = {
className: PropTypes.string,
};

export default Sidebar;
Loading

0 comments on commit 746e5b7

Please sign in to comment.