Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add totalValue filter #45170

Merged
merged 8 commits into from Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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.