show discount on cart line items & price styling (https://github.com/woocommerce/woocommerce-blocks/pull/1548)

* show discount on cart line items (no styling)

* style line item discount badge + use correct colors for prices

* show full price inline on mobile

* move all responsive tweaks for cart prices to explicit breakpoints

* add nowrap to FormattedMoneyAmount so prices don't ever wrap

* fix misaligned full price on mobile when prices are large (edge case):
- if price strings are long, the full price stacks above line total
- previous right-margin on full price showed prices misaligned

* allow client code to add class(es) to FormattedMonetaryAmount

* add nowrap so discount badge doesn't wrap

* remove unnecessary span from discount badge +
+ more explicit `display` style for different price column elements
This commit is contained in:
Rua Haszard 2020-01-15 09:52:42 +13:00 committed by GitHub
parent b9bfef0ba4
commit 86dca691e5
4 changed files with 97 additions and 12 deletions

View File

@ -2,6 +2,12 @@
* External dependencies
*/
import NumberFormat from 'react-number-format';
import classNames from 'classnames';
/**
* Internal dependencies
*/
import './style.scss';
/**
* Formats currency data into the expected format for NumberFormat.
@ -29,6 +35,7 @@ const currencyToNumberFormat = ( currency ) => {
* @param {Object} props Component props.
*/
const FormattedMonetaryAmount = ( {
className,
value,
currency,
onValueChange,
@ -40,6 +47,7 @@ const FormattedMonetaryAmount = ( {
return null;
}
const classes = classNames( 'wc-block-formatted-money-amount', className );
const numberFormatProps = {
displayType: 'text',
...props,
@ -59,6 +67,7 @@ const FormattedMonetaryAmount = ( {
return (
<NumberFormat
className={ classes }
{ ...numberFormatProps }
value={ priceValue }
onValueChange={ onValueChangeWrapper }

View File

@ -0,0 +1,3 @@
.wc-block-formatted-money-amount {
white-space: nowrap;
}

View File

@ -6,7 +6,21 @@ import { __, sprintf } 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 } from '@woocommerce/base-utils';
import { getCurrency, formatPrice } from '@woocommerce/base-utils';
/**
* Return the difference between two price amounts, e.g. a discount.
*
* @param {string} subtotal Currency value in minor unit, e.g. cents.
* @param {string} total Currency value in minor unit, e.g. cents.
* @return {number} The difference (discount).
*/
const calcPriceDifference = ( subtotal, total ) => {
const subtotalValue = parseInt( subtotal, 10 );
const totalValue = parseInt( total, 10 );
return subtotalValue - totalValue;
};
const ProductVariationDetails = ( { variation } ) => {
const variationsText = variation
@ -43,12 +57,28 @@ const CartLineItemRow = ( { lineItem } ) => {
const [ lineQuantity, setLineQuantity ] = useState( quantity );
const currency = getCurrency();
const isDiscounted = subtotal !== total;
const fullPrice = isDiscounted ? (
<div className="wc-block-cart-item__full-price">
<FormattedMonetaryAmount currency={ currency } value={ subtotal } />
</div>
) : null;
const discountAmount = calcPriceDifference( subtotal, total );
let fullPrice = null,
discountBadge = null;
if ( discountAmount > 0 ) {
fullPrice = (
<div className="wc-block-cart-item__full-price">
<FormattedMonetaryAmount
currency={ currency }
value={ subtotal }
/>
</div>
);
discountBadge = (
<div className="wc-block-cart-item__discount-badge">
{ sprintf(
/* translators: %s discount amount */
__( 'Save %s!', 'woo-gutenberg-products-block' ),
formatPrice( discountAmount, currency )
) }
</div>
);
}
// We use this in two places so we can stack the quantity selector under
// product info on smaller screens.
@ -104,10 +134,13 @@ const CartLineItemRow = ( { lineItem } ) => {
</td>
<td className="wc-block-cart-item__total">
{ fullPrice }
<FormattedMonetaryAmount
currency={ currency }
value={ total }
/>
<div className="wc-block-cart-item__line-total">
<FormattedMonetaryAmount
currency={ currency }
value={ total }
/>
</div>
{ discountBadge }
</td>
</tr>
);

View File

@ -86,13 +86,30 @@ table.wc-block-cart-items {
.wc-block-cart-item__total {
vertical-align: bottom;
font-size: 16px;
line-height: 19px;
}
.wc-block-cart-item__full-price {
color: $core-grey-light-800;
color: $core-grey-dark-400;
text-decoration: line-through;
}
.wc-block-cart-item__line-total {
color: $black;
margin-left: 0.5em;
}
.wc-block-cart-item__discount-badge {
background-color: $core-grey-dark-600;
border-radius: 3px;
color: $white;
font-size: 12px;
padding: 0 1em;
text-transform: uppercase;
white-space: nowrap;
}
.wc-block-cart__totals-footer {
color: #000;
font-size: 1.25em;
@ -137,6 +154,16 @@ table.wc-block-cart-items {
.wc-block-cart__totals-title {
display: none;
}
.wc-block-cart-item__line-total,
.wc-block-cart-item__full-price {
// inline on mobile, so line prices are aligned vertically
display: inline-block;
}
.wc-block-cart-item__discount-badge {
display: none;
}
}
@include breakpoint( ">782px" ) {
@ -184,4 +211,17 @@ table.wc-block-cart-items {
.wc-block-cart-item__total {
vertical-align: top;
}
.wc-block-cart-item__line-total,
.wc-block-cart-item__full-price {
display: block;
}
.wc-block-cart-item__full-price {
margin-right: 0;
}
.wc-block-cart-item__discount-badge {
display: inline-block;
}
}