Skip to content

Commit

Permalink
Add totalValue filter (#45170)
Browse files Browse the repository at this point in the history
* Add totalValue filter

* Add changefile(s) from automation for the following project(s): woocommerce-blocks

* Remove nowrap to prevent text overflow

* Start docs for ‘totalValue’ filter

* Fix *.md lint issues

* Ignore .md lint errors for now

* Update code example and add screenshots

* Fix failing JS unit tests

---------

Co-authored-by: github-actions <github-actions@github.com>
  • Loading branch information
nielslange and github-actions committed Mar 12, 2024
1 parent 55ec9ec commit 6b07ca4
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 53 deletions.
Expand Up @@ -13,7 +13,10 @@ import {
useStoreCart,
} from '@woocommerce/base-context/hooks';
import { getCurrencyFromPriceResponse } from '@woocommerce/price-format';
import { applyCheckoutFilter, mustContain } from '@woocommerce/blocks-checkout';
import {
applyCheckoutFilter,
productPriceValidation,
} from '@woocommerce/blocks-checkout';
import Dinero from 'dinero.js';
import { forwardRef, useMemo } from '@wordpress/element';
import type { CartItem } from '@woocommerce/types';
Expand Down Expand Up @@ -43,9 +46,6 @@ const getAmountFromRawPrice = (
return priceObject.convertPrecision( currency.minorUnit ).getAmount();
};

const productPriceValidation = ( value: string ) =>
mustContain( value, '<price/>' );

interface CartLineItemRowProps {
lineItem: CartItem | Record< string, never >;
onRemove?: () => void;
Expand Down
Expand Up @@ -10,7 +10,10 @@ import {
getCurrencyFromPriceResponse,
formatPrice,
} from '@woocommerce/price-format';
import { applyCheckoutFilter, mustContain } from '@woocommerce/blocks-checkout';
import {
applyCheckoutFilter,
productPriceValidation,
} from '@woocommerce/blocks-checkout';
import Dinero from 'dinero.js';
import { getSetting } from '@woocommerce/settings';
import { useMemo } from '@wordpress/element';
Expand All @@ -25,9 +28,6 @@ import ProductImage from '../product-image';
import ProductLowStockBadge from '../product-low-stock-badge';
import ProductMetadata from '../product-metadata';

const productPriceValidation = ( value: string ): true | never =>
mustContain( value, '<price/>' );

interface OrderSummaryProps {
cartItem: CartItem;
}
Expand Down
Expand Up @@ -8,7 +8,10 @@ import {
FormattedMonetaryAmount,
TotalsItem,
} from '@woocommerce/blocks-components';
import { applyCheckoutFilter } from '@woocommerce/blocks-checkout';
import {
applyCheckoutFilter,
productPriceValidation,
} from '@woocommerce/blocks-checkout';
import { useStoreCart } from '@woocommerce/base-context/hooks';
import { getSetting } from '@woocommerce/settings';
import {
Expand Down Expand Up @@ -64,14 +67,36 @@ const TotalsFooterItem = ( {
// We need to pluck out receiveCart.
// eslint-disable-next-line no-unused-vars
const { receiveCart, ...cart } = useStoreCart();

const label = applyCheckoutFilter( {
filterName: 'totalLabel',
defaultValue: __( 'Total', 'woocommerce' ),
extensions: cart.extensions,
arg: { cart },
} );

const totalValue = applyCheckoutFilter( {
filterName: 'totalValue',
defaultValue: '<price/>',
extensions: cart.extensions,
arg: { cart },
validation: productPriceValidation,
} );

const priceComponent = (
<FormattedMonetaryAmount
className="wc-block-components-totals-item__value"
currency={ currency }
value={ parseInt( totalPrice, 10 ) }
/>
);

const value = createInterpolateElement( totalValue, {
price: priceComponent,
} );

const parsedTaxValue = parseInt( totalTax, 10 );

const description =
taxLines && taxLines.length > 0
? sprintf(
Expand All @@ -96,7 +121,7 @@ const TotalsFooterItem = ( {
) }
currency={ currency }
label={ label }
value={ parseInt( totalPrice, 10 ) }
value={ value }
description={
SHOW_TAXES &&
parsedTaxValue !== 0 && (
Expand Down
17 changes: 8 additions & 9 deletions plugins/woocommerce-blocks/docs/README.md
Expand Up @@ -2,14 +2,14 @@

## Table of Contents <!-- omit in toc -->

- [Contributors](#contributors)
- [Internal developers](#internal-developers)
- [Third-party developers](#third-party-developers)
- [Designers](#designers)
- [Developer Resources](#developer-resources)
- [Tools](#tools)
- [Articles](#articles)
- [Tutorials](#tutorials)
- [Contributors](#contributors)
- [Internal developers](#internal-developers)
- [Third-party developers](#third-party-developers)
- [Designers](#designers)
- [Developer Resources](#developer-resources)
- [Tools](#tools)
- [Articles](#articles)
- [Tutorials](#tutorials)

The WooCommerce Blocks Handbook provides documentation for designers and developers on how to extend or contribute to blocks, and how internal developers should handle new releases.

Expand Down Expand Up @@ -152,4 +152,3 @@ The following tutorials from [developer.woo.com](https://developer.woo.com/categ
🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/README.md)

<!-- /FEEDBACK -->

Expand Up @@ -2,25 +2,25 @@

## Table of Contents <!-- omit in toc -->

- [General Concepts](#general-concepts)
- [Tracking flow through status](#tracking-flow-through-status)
- [Checkout Data Store Status](#checkout-data-store-status)
- [Special States](#special-states)
- [`ShippingProvider` Exposed Statuses](#shippingprovider-exposed-statuses)
- [Payment Method Data Store Status](#payment-method-data-store-status)
- [Emitting Events](#emitting-events)
- [`onCheckoutValidation`](#oncheckoutvalidation)
- [~~`onPaymentProcessing`~~](#onpaymentprocessing)
- [`onPaymentSetup`](#onpaymentsetup)
- [Success](#success)
- [Fail](#fail)
- [Error](#error)
- [`onCheckoutSuccess`](#oncheckoutsuccess)
- [`onCheckoutFail`](#oncheckoutfail)
- [`onShippingRateSuccess`](#onshippingratesuccess)
- [`onShippingRateFail`](#onshippingratefail)
- [`onShippingRateSelectSuccess`](#onshippingrateselectsuccess)
- [`onShippingRateSelectFail`](#onshippingrateselectfail)
- [General Concepts](#general-concepts)
- [Tracking flow through status](#tracking-flow-through-status)
- [Checkout Data Store Status](#checkout-data-store-status)
- [Special States](#special-states)
- [`ShippingProvider` Exposed Statuses](#shippingprovider-exposed-statuses)
- [Payment Method Data Store Status](#payment-method-data-store-status)
- [Emitting Events](#emitting-events)
- [`onCheckoutValidation`](#oncheckoutvalidation)
- [~~`onPaymentProcessing`~~](#onpaymentprocessing)
- [`onPaymentSetup`](#onpaymentsetup)
- [Success](#success)
- [Fail](#fail)
- [Error](#error)
- [`onCheckoutSuccess`](#oncheckoutsuccess)
- [`onCheckoutFail`](#oncheckoutfail)
- [`onShippingRateSuccess`](#onshippingratesuccess)
- [`onShippingRateFail`](#onshippingratefail)
- [`onShippingRateSelectSuccess`](#onshippingrateselectsuccess)
- [`onShippingRateSelectFail`](#onshippingrateselectfail)

This document gives an overview of the flow for the checkout in the WooCommerce checkout block, and some general architectural overviews.

Expand Down
Expand Up @@ -45,15 +45,16 @@ The following screenshot shows which parts the individual filters affect:

The following [Totals Footer Item filter](./available-filters/totals-footer-item.md) is available:

- [totalLabel](./available-filters/totals-footer-item.md#totallabel)
- [`totalLabel`](./available-filters/totals-footer-item.md#totallabel)
- [`totalValue`](./available-filters/totals-footer-item.md#totalvalue)

## Checkout and place order button filters

The following [Checkout and place order button filters](./available-filters/checkout-and-place-order-button.md) are available:

- [proceedToCheckoutButtonLabel](./available-filters/checkout-and-place-order-button.md#proceedtocheckoutbuttonlabel)
- [proceedToCheckoutButtonLink](./available-filters/checkout-and-place-order-button.md#proceedtocheckoutbuttonlink)
- [placeOrderButtonLabel](./available-filters/checkout-and-place-order-button.md#placeorderbuttonlabel)
- [`proceedToCheckoutButtonLabel`](./available-filters/checkout-and-place-order-button.md#proceedtocheckoutbuttonlabel)
- [`proceedToCheckoutButtonLink`](./available-filters/checkout-and-place-order-button.md#proceedtocheckoutbuttonlink)
- [`placeOrderButtonLabel`](./available-filters/checkout-and-place-order-button.md#placeorderbuttonlabel)

## Coupon filters

Expand Down
@@ -1,19 +1,22 @@
<!-- markdownlint-disable MD024 -->
<!-- markdownlint-disable MD033 -->

# Totals Footer Item

The following Totals Footer Item filter is available:
The following Totals Footer Item filter are available:

- [totalLabel](#totallabel)
- [`totalLabel`](#totallabel)
- [`totalValue`](#totalvalue)

## `totalLabel`

The following objects are used in the filter:
The following object is used in the filter:

- [Cart object](#cart-object)
- [Cart Item object](#cart-item-object)

### Description <!-- omit in toc -->

The `totalLabel` filter allows you to change the label of the total item in the footer of the Cart and Checkout blocks.
The `totalLabel` filter allows to change the label of the total item in the footer of the Cart and Checkout blocks.

### Parameters <!-- omit in toc -->

Expand Down Expand Up @@ -57,6 +60,59 @@ registerCheckoutFilters( 'example-extension', {
</tr>
</table>

## `totalValue`

The following object is used in the filter:

- [Cart object](#cart-object)

### Description <!-- omit in toc -->

The `totalValue` filter allows to format the total price in the footer of the Cart and Checkout blocks.

### Parameters <!-- omit in toc -->

- _defaultValue_ `string` (default: `Total`) - The total label.
- _extensions_ `object` (default: `{}`) - The extensions object.
- _args_ `object` - The arguments object with the following keys:
- _cart_ `object` - The cart object from `wc/store/cart`, see [Cart object](#cart-object).
- _validation_ `boolean` - Checks if the return value contains the substring `<price/>`.

### Returns <!-- omit in toc -->

- `string` - The modified format of the total price, which must contain the substring `<price/>`, or the original price format.

### Code example <!-- omit in toc -->

```ts
const { registerCheckoutFilters } = window.wc.blocksCheckout;

const modifyTotalsPrice = ( defaultValue, extensions, args, validation ) => {
return 'Pay <price/> now';
};

registerCheckoutFilters( 'my-extension', {
totalValue: modifyTotalsPrice,
} );
```

> 💡 Filters can be also combined. See [Combined filters](../available-filters.md#combined-filters) for an example.
### Screenshots <!-- omit in toc -->

<table>
<tr>
<td valign="top">Before:
<br><br>
<img width="361" alt="Before applying the Total Value filter" src="https://github.com/woocommerce/woocommerce/assets/3323310/4b788bdd-6fbd-406c-a9ad-4fb13f901c23">
</td>
<td valign="top">After:
<br><br>
<img width="355" alt="After applying the Total Value filter" src="https://github.com/woocommerce/woocommerce/assets/3323310/1b1b5f72-7f2f-4ee5-b2a4-1d8eb2208deb">
</td>
</tr>
</table>

## Cart object

The Cart object of the filters above has the following keys:
Expand Down
@@ -1,3 +1,4 @@
export { default as mustContain } from './must-contain';
export { default as getValidityMessageForInput } from './get-validity-message-for-input';
export { default as isPostcode } from './is-postcode';
export { productPriceValidation } from './validate-filter';
@@ -0,0 +1,7 @@
/**
* Internal dependencies
*/
import mustContain from './must-contain';

export const productPriceValidation = ( value: string ) =>
mustContain( value, '<price/>' );
Expand Up @@ -26,11 +26,7 @@ const TotalsItemValue = ( {
currency,
}: Partial< TotalsItemProps > ): ReactElement | null => {
if ( isValidElement( value ) ) {
return (
<div className="wc-block-components-totals-item__value">
{ value }
</div>
);
return <>{ value }</>;
}

return Number.isFinite( value ) ? (
Expand Down
Expand Up @@ -11,7 +11,6 @@

.wc-block-components-totals-item__value {
font-weight: bold;
white-space: nowrap;
}

.wc-block-components-totals-item__description {
Expand Down
@@ -0,0 +1,4 @@
Significance: minor
Type: add

Add totalValue filter.

0 comments on commit 6b07ca4

Please sign in to comment.