Extensibility: Format currency config so it can be consumed more easily (#48727)

* Export pre-formatted SITE_CURRENCY object from settings

* Fallback to SITE_CURRENCY

* Changelog

* Fix typedef

* Update mocks

* Inject site currency into cart preview data

* Update test

* Add currency formatting to preview data

* Mock currency in tests

* More currency mocking
This commit is contained in:
Mike Jolley 2024-07-12 14:24:22 +01:00 committed by GitHub
parent b9d6439b9d
commit e0c62dce79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 289 additions and 245 deletions

View File

@ -46,6 +46,19 @@ const defaultUseStoreCartValue = {
cartHasCalculatedShipping: mockPreviewCart.has_calculated_shipping,
};
jest.mock( '@woocommerce/settings', () => ( {
...jest.requireActual( '@woocommerce/settings' ),
SITE_CURRENCY: {
code: 'USD',
symbol: '$',
thousandSeparator: ',',
decimalSeparator: '.',
minorUnit: 2,
prefix: '$',
suffix: '',
},
} ) );
jest.mock( '@woocommerce/base-context/hooks', () => ( {
...jest.requireActual( '@woocommerce/base-context/hooks' ),
@ -182,6 +195,15 @@ jest.mock( '@woocommerce/settings', () => {
return {
...originalModule,
SITE_CURRENCY: {
code: 'USD',
symbol: '$',
thousandSeparator: ',',
decimalSeparator: '.',
minorUnit: 2,
prefix: '$',
suffix: '',
},
getSetting: jest.fn().mockImplementation( ( setting, ...rest ) => {
if ( setting === 'couponsEnabled' ) {
return true;

View File

@ -10,6 +10,7 @@ import { getSetting } from '@woocommerce/settings';
* Internal dependencies
*/
import { previewShippingRates } from './shipping-rates';
import { API_SITE_CURRENCY, displayForMinorUnit } from './utils';
/**
* Prices from the API may change because of this display setting. This makes the response use either
@ -81,16 +82,16 @@ export const previewCart: CartResponse = {
},
],
prices: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
price: displayWithTax ? '12000' : '10000',
regular_price: displayWithTax ? '12000' : '10000',
sale_price: displayWithTax ? '12000' : '10000',
...API_SITE_CURRENCY,
price: displayForMinorUnit(
displayWithTax ? '12000' : '10000'
),
regular_price: displayForMinorUnit(
displayWithTax ? '120' : '100'
),
sale_price: displayForMinorUnit(
displayWithTax ? '12000' : '10000'
),
price_range: null,
raw_prices: {
precision: 6,
@ -100,17 +101,11 @@ export const previewCart: CartResponse = {
},
},
totals: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
line_subtotal: '2000',
line_subtotal_tax: '400',
line_total: '2000',
line_total_tax: '400',
...API_SITE_CURRENCY,
line_subtotal: displayForMinorUnit( '2000' ),
line_subtotal_tax: displayForMinorUnit( '400' ),
line_total: displayForMinorUnit( '2000' ),
line_total_tax: displayForMinorUnit( '400' ),
},
extensions: {},
item_data: [],
@ -156,16 +151,14 @@ export const previewCart: CartResponse = {
},
],
prices: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
price: displayWithTax ? '2400' : '2000',
regular_price: displayWithTax ? '2400' : '2000',
sale_price: displayWithTax ? '2400' : '2000',
...API_SITE_CURRENCY,
price: displayForMinorUnit( displayWithTax ? '2400' : '2000' ),
regular_price: displayForMinorUnit(
displayWithTax ? '2400' : '2000'
),
sale_price: displayForMinorUnit(
displayWithTax ? '2400' : '2000'
),
price_range: null,
raw_prices: {
precision: 6,
@ -175,17 +168,11 @@ export const previewCart: CartResponse = {
},
},
totals: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
line_subtotal: '2000',
line_subtotal_tax: '400',
line_total: '2000',
line_total_tax: '400',
...API_SITE_CURRENCY,
line_subtotal: displayForMinorUnit( '2000' ),
line_subtotal_tax: displayForMinorUnit( '400' ),
line_total: displayForMinorUnit( '2000' ),
line_total_tax: displayForMinorUnit( '400' ),
},
extensions: {},
item_data: [],
@ -195,6 +182,7 @@ export const previewCart: CartResponse = {
{
id: 1,
name: __( 'Polo', 'woocommerce' ),
slug: 'polo',
parent: 0,
type: 'simple',
variation: '',
@ -204,16 +192,16 @@ export const previewCart: CartResponse = {
description: __( 'Polo', 'woocommerce' ),
on_sale: false,
prices: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
price: displayWithTax ? '24000' : '20000',
regular_price: displayWithTax ? '24000' : '20000',
sale_price: displayWithTax ? '12000' : '10000',
...API_SITE_CURRENCY,
price: displayForMinorUnit(
displayWithTax ? '24000' : '20000'
),
regular_price: displayForMinorUnit(
displayWithTax ? '24000' : '20000'
),
sale_price: displayForMinorUnit(
displayWithTax ? '12000' : '10000'
),
price_range: null,
},
price_html: '',
@ -252,6 +240,7 @@ export const previewCart: CartResponse = {
{
id: 2,
name: __( 'Long Sleeve Tee', 'woocommerce' ),
slug: 'long-sleeve-tee',
parent: 0,
type: 'simple',
variation: '',
@ -261,16 +250,16 @@ export const previewCart: CartResponse = {
description: __( 'Long Sleeve Tee', 'woocommerce' ),
on_sale: false,
prices: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
price: displayWithTax ? '30000' : '25000',
regular_price: displayWithTax ? '30000' : '25000',
sale_price: displayWithTax ? '30000' : '25000',
...API_SITE_CURRENCY,
price: displayForMinorUnit(
displayWithTax ? '30000' : '25000'
),
regular_price: displayForMinorUnit(
displayWithTax ? '30000' : '25000'
),
sale_price: displayForMinorUnit(
displayWithTax ? '30000' : '25000'
),
price_range: null,
},
price_html: '',
@ -310,6 +299,7 @@ export const previewCart: CartResponse = {
{
id: 3,
name: __( 'Hoodie with Zipper', 'woocommerce' ),
slug: 'hoodie-with-zipper',
parent: 0,
type: 'simple',
variation: '',
@ -319,16 +309,16 @@ export const previewCart: CartResponse = {
description: __( 'Hoodie with Zipper', 'woocommerce' ),
on_sale: true,
prices: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
price: displayWithTax ? '15000' : '12500',
regular_price: displayWithTax ? '30000' : '25000',
sale_price: displayWithTax ? '15000' : '12500',
...API_SITE_CURRENCY,
price: displayForMinorUnit(
displayWithTax ? '15000' : '12500'
),
regular_price: displayForMinorUnit(
displayWithTax ? '30000' : '25000'
),
sale_price: displayForMinorUnit(
displayWithTax ? '15000' : '12500'
),
price_range: null,
},
price_html: '',
@ -369,6 +359,7 @@ export const previewCart: CartResponse = {
{
id: 4,
name: __( 'Hoodie with Logo', 'woocommerce' ),
slug: 'hoodie-with-logo',
parent: 0,
type: 'simple',
variation: '',
@ -378,16 +369,14 @@ export const previewCart: CartResponse = {
description: __( 'Polo', 'woocommerce' ),
on_sale: false,
prices: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
price: displayWithTax ? '4500' : '4250',
regular_price: displayWithTax ? '4500' : '4250',
sale_price: displayWithTax ? '4500' : '4250',
...API_SITE_CURRENCY,
price: displayForMinorUnit( displayWithTax ? '4500' : '4250' ),
regular_price: displayForMinorUnit(
displayWithTax ? '4500' : '4250'
),
sale_price: displayForMinorUnit(
displayWithTax ? '4500' : '4250'
),
price_range: null,
},
price_html: '',
@ -427,6 +416,7 @@ export const previewCart: CartResponse = {
{
id: 5,
name: __( 'Hoodie with Pocket', 'woocommerce' ),
slug: 'hoodie-with-pocket',
parent: 0,
type: 'simple',
variation: '',
@ -436,16 +426,14 @@ export const previewCart: CartResponse = {
description: __( 'Hoodie with Pocket', 'woocommerce' ),
on_sale: true,
prices: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
price: displayWithTax ? '3500' : '3250',
regular_price: displayWithTax ? '4500' : '4250',
sale_price: displayWithTax ? '3500' : '3250',
...API_SITE_CURRENCY,
price: displayForMinorUnit( displayWithTax ? '3500' : '3250' ),
regular_price: displayForMinorUnit(
displayWithTax ? '4500' : '4250'
),
sale_price: displayForMinorUnit(
displayWithTax ? '3500' : '3250'
),
price_range: null,
},
price_html: '',
@ -486,6 +474,7 @@ export const previewCart: CartResponse = {
{
id: 6,
name: __( 'T-Shirt', 'woocommerce' ),
slug: 't-shirt',
parent: 0,
type: 'simple',
variation: '',
@ -495,16 +484,14 @@ export const previewCart: CartResponse = {
description: __( 'T-Shirt', 'woocommerce' ),
on_sale: false,
prices: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
price: displayWithTax ? '1800' : '1500',
regular_price: displayWithTax ? '1800' : '1500',
sale_price: displayWithTax ? '1800' : '1500',
...API_SITE_CURRENCY,
price: displayForMinorUnit( displayWithTax ? '1800' : '1500' ),
regular_price: displayForMinorUnit(
displayWithTax ? '1800' : '1500'
),
sale_price: displayForMinorUnit(
displayWithTax ? '1800' : '1500'
),
price_range: null,
},
price_html: '',
@ -546,15 +533,9 @@ export const previewCart: CartResponse = {
id: 'fee',
name: __( 'Fee', 'woocommerce' ),
totals: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
total: '100',
total_tax: '20',
...API_SITE_CURRENCY,
total: displayForMinorUnit( '100' ),
total_tax: displayForMinorUnit( '20' ),
},
},
],
@ -589,28 +570,22 @@ export const previewCart: CartResponse = {
phone: '',
},
totals: {
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
total_items: '4000',
total_items_tax: '800',
total_fees: '100',
total_fees_tax: '20',
...API_SITE_CURRENCY,
total_items: displayForMinorUnit( '4000' ),
total_items_tax: displayForMinorUnit( '800' ),
total_fees: displayForMinorUnit( '100' ),
total_fees_tax: displayForMinorUnit( '20' ),
total_discount: '0',
total_discount_tax: '0',
total_shipping: '0',
total_shipping_tax: '0',
total_tax: '820',
total_price: '4920',
total_tax: displayForMinorUnit( '820' ),
total_price: displayForMinorUnit( '4920' ),
tax_lines: [
{
name: __( 'Sales tax', 'woocommerce' ),
rate: '20%',
price: '820',
price: displayForMinorUnit( '820' ),
},
],
},

View File

@ -4,6 +4,11 @@
import { __, _x } from '@wordpress/i18n';
import type { CartResponseShippingRate } from '@woocommerce/types';
/**
* Internal dependencies
*/
import { API_SITE_CURRENCY, displayForMinorUnit } from './utils';
export const previewShippingRates: CartResponseShippingRate[] = [
{
destination: {
@ -38,32 +43,20 @@ export const previewShippingRates: CartResponseShippingRate[] = [
],
shipping_rates: [
{
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
...API_SITE_CURRENCY,
name: __( 'Flat rate shipping', 'woocommerce' ),
description: '',
delivery_time: '',
price: '500',
price: displayForMinorUnit( '500' ),
taxes: '0',
rate_id: 'flat_rate:0',
instance_id: 0,
meta_data: [],
method_id: 'flat_rate',
selected: true,
selected: false,
},
{
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
...API_SITE_CURRENCY,
name: __( 'Free shipping', 'woocommerce' ),
description: '',
delivery_time: '',
@ -73,16 +66,10 @@ export const previewShippingRates: CartResponseShippingRate[] = [
instance_id: 0,
meta_data: [],
method_id: 'flat_rate',
selected: false,
selected: true,
},
{
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
...API_SITE_CURRENCY,
name: __( 'Local pickup', 'woocommerce' ),
description: '',
delivery_time: '',
@ -104,13 +91,7 @@ export const previewShippingRates: CartResponseShippingRate[] = [
selected: false,
},
{
currency_code: 'USD',
currency_symbol: '$',
currency_minor_unit: 2,
currency_decimal_separator: '.',
currency_thousand_separator: ',',
currency_prefix: '$',
currency_suffix: '',
...API_SITE_CURRENCY,
name: __( 'Local pickup', 'woocommerce' ),
description: '',
delivery_time: '',

View File

@ -0,0 +1,34 @@
/**
* External dependencies
*/
import { SITE_CURRENCY } from '@woocommerce/settings';
/**
* Put site currency back in API format for the responses.
*/
export const API_SITE_CURRENCY = {
currency_code: SITE_CURRENCY.code,
currency_symbol: SITE_CURRENCY.symbol,
currency_minor_unit: SITE_CURRENCY.minorUnit,
currency_decimal_separator: SITE_CURRENCY.decimalSeparator,
currency_thousand_separator: SITE_CURRENCY.thousandSeparator,
currency_prefix: SITE_CURRENCY.prefix,
currency_suffix: SITE_CURRENCY.suffix,
};
/**
* Preview data is defined with 2dp. This converts to selected currency settings.
*/
export const displayForMinorUnit = ( value: string ): string => {
const minorUnit = SITE_CURRENCY.minorUnit;
// Preview data is defined with 2 dp.
if ( minorUnit === 2 ) {
return value;
}
const multiplier = Math.pow( 10, minorUnit );
const intValue = Math.round( parseInt( value, 10 ) / Math.pow( 10, 2 ) );
return ( intValue * multiplier ).toString();
};

View File

@ -1,14 +1,19 @@
/**
* External dependencies
*/
import type { Currency, SymbolPosition } from '@woocommerce/types';
/**
* Internal dependencies
*/
import { allSettings } from './settings-init';
import { getCurrencyPrefix, getCurrencySuffix } from './utils';
/**
* This exports all default core settings as constants.
*/
export const ADMIN_URL = allSettings.adminUrl;
export const COUNTRIES = allSettings.countries;
export const CURRENCY = allSettings.currency;
export const CURRENT_USER_IS_ADMIN = allSettings.currentUserIsAdmin as boolean;
export const HOME_URL = allSettings.homeUrl as string | undefined;
export const LOCALE = allSettings.locale;
@ -27,3 +32,22 @@ export const WC_ASSET_URL = allSettings.wcAssetUrl;
export const WC_VERSION = allSettings.wcVersion;
export const WP_LOGIN_URL = allSettings.wpLoginUrl;
export const WP_VERSION = allSettings.wpVersion;
// Settings from the server in WooCommerceSiteCurrency format.
export const CURRENCY = allSettings.currency;
// Convert WooCommerceSiteCurrency format to Currency format.
export const SITE_CURRENCY: Currency = {
code: CURRENCY.code,
symbol: CURRENCY.symbol,
thousandSeparator: CURRENCY.thousandSeparator,
decimalSeparator: CURRENCY.decimalSeparator,
minorUnit: CURRENCY.precision,
prefix: getCurrencyPrefix(
CURRENCY.symbol,
CURRENCY.symbolPosition as SymbolPosition
),
suffix: getCurrencySuffix(
CURRENCY.symbol,
CURRENCY.symbolPosition as SymbolPosition
),
};

View File

@ -2,6 +2,7 @@
* External dependencies
*/
import compareVersions from 'compare-versions';
import type { SymbolPosition } from '@woocommerce/types';
/**
* Internal dependencies
@ -138,3 +139,35 @@ export const getPaymentMethodData = (
>;
return paymentMethodData[ paymentMethodId ] ?? defaultValue;
};
/**
* Get currency prefix.
*/
export const getCurrencyPrefix = (
symbol: string,
symbolPosition: SymbolPosition
): string => {
const prefixes = {
left: symbol,
left_space: symbol + ' ',
right: '',
right_space: '',
};
return prefixes[ symbolPosition ] || '';
};
/**
* Get currency suffix.
*/
export const getCurrencySuffix = (
symbol: string,
symbolPosition: SymbolPosition
): string => {
const suffixes = {
left: '',
left_space: '',
right: symbol,
right_space: ' ' + symbol,
};
return suffixes[ symbolPosition ] || '';
};

View File

@ -9,6 +9,7 @@ import type {
import clsx from 'clsx';
import type { ReactElement } from 'react';
import type { Currency } from '@woocommerce/types';
import { SITE_CURRENCY } from '@woocommerce/settings';
/**
* Internal dependencies
@ -22,7 +23,7 @@ export interface FormattedMonetaryAmountProps
allowNegative?: boolean;
isAllowed?: ( formattedValue: NumberFormatValues ) => boolean;
value: number | string; // Value of money amount.
currency: Currency | Record< string, never >; // Currency configuration object.
currency?: Currency | undefined; // Currency configuration object. Defaults to site currency.
onValueChange?: ( unit: number ) => void; // Function to call when value changes.
style?: React.CSSProperties | undefined;
renderText?: ( value: string ) => JSX.Element;
@ -31,36 +32,25 @@ export interface FormattedMonetaryAmountProps
/**
* Formats currency data into the expected format for NumberFormat.
*/
const currencyToNumberFormat = (
currency: FormattedMonetaryAmountProps[ 'currency' ]
) => {
const hasSimiliarSeparators =
currency?.thousandSeparator === currency?.decimalSeparator;
if ( hasSimiliarSeparators ) {
const currencyToNumberFormat = ( currency: Currency ) => {
const { prefix, suffix, thousandSeparator, decimalSeparator } = currency;
const hasDuplicateSeparator = thousandSeparator === decimalSeparator;
if ( hasDuplicateSeparator ) {
// eslint-disable-next-line no-console
console.warn(
'Thousand separator and decimal separator are the same. This may cause formatting issues.'
);
}
return {
thousandSeparator: hasSimiliarSeparators
? ''
: currency?.thousandSeparator,
decimalSeparator: currency?.decimalSeparator,
thousandSeparator: hasDuplicateSeparator ? '' : thousandSeparator,
decimalSeparator,
fixedDecimalScale: true,
prefix: currency?.prefix,
suffix: currency?.suffix,
prefix,
suffix,
isNumericString: true,
};
};
type CustomFormattedMonetaryAmountProps = Omit<
FormattedMonetaryAmountProps,
'currency'
> & {
currency: Currency | Record< string, never >;
};
/**
* FormattedMonetaryAmount component.
*
@ -71,11 +61,18 @@ type CustomFormattedMonetaryAmountProps = Omit<
const FormattedMonetaryAmount = ( {
className,
value: rawValue,
currency,
currency: rawCurrency = SITE_CURRENCY,
onValueChange,
displayType = 'text',
...props
}: CustomFormattedMonetaryAmountProps ): ReactElement | null => {
}: FormattedMonetaryAmountProps ): ReactElement | null => {
// Merge currency configuration with site currency.
const currency = {
...SITE_CURRENCY,
...rawCurrency,
};
// Convert values to int.
const value =
typeof rawValue === 'string' ? parseInt( rawValue, 10 ) : rawValue;

View File

@ -8,8 +8,27 @@ import { render, screen } from '@testing-library/react';
*/
import FormattedMonetaryAmount from '../index';
jest.mock( '@woocommerce/settings', () => ( {
...jest.requireActual( '@woocommerce/settings' ),
SITE_CURRENCY: {
code: 'EUR',
symbol: 'TEST',
thousandSeparator: '.',
decimalSeparator: ',',
minorUnit: 2,
prefix: '',
suffix: ' TEST',
},
} ) );
describe( 'FormattedMonetaryAmount', () => {
describe( 'separators', () => {
test( 'should default to store currency configuration', () => {
render( <FormattedMonetaryAmount value="156345" /> );
expect( screen.getByText( '1.563,45 TEST' ) ).toBeInTheDocument();
} );
test( 'should add the thousand separator', () => {
render(
<FormattedMonetaryAmount
@ -37,6 +56,7 @@ describe( 'FormattedMonetaryAmount', () => {
code: 'EUR',
symbol: '€',
decimalSeparator: ',',
thousandSeparator: '',
minorUnit: 2,
prefix: '',
suffix: ' €',
@ -76,6 +96,7 @@ describe( 'FormattedMonetaryAmount', () => {
thousandSeparator: '.',
decimalSeparator: ',',
minorUnit: 2,
prefix: '',
suffix: ' €',
} }
/>
@ -94,6 +115,7 @@ describe( 'FormattedMonetaryAmount', () => {
decimalSeparator: ',',
minorUnit: 2,
prefix: '€ ',
suffix: '',
} }
/>
);
@ -112,6 +134,7 @@ describe( 'FormattedMonetaryAmount', () => {
thousandSeparator: '.',
decimalSeparator: ',',
minorUnit: 0,
prefix: '',
suffix: ' €',
} }
/>
@ -130,6 +153,7 @@ describe( 'FormattedMonetaryAmount', () => {
decimalSeparator: ',',
minorUnit: 0,
prefix: '€ ',
suffix: '',
} }
/>
);

View File

@ -1,69 +1,13 @@
/**
* External dependencies
*/
import { CURRENCY } from '@woocommerce/settings';
import { SITE_CURRENCY } from '@woocommerce/settings';
import type {
Currency,
CurrencyResponse,
CartShippingPackageShippingRate,
SymbolPosition,
} from '@woocommerce/types';
/**
* Get currency prefix.
*/
const getPrefix = (
// Currency symbol.
symbol: string,
// Position of currency symbol from settings.
symbolPosition: SymbolPosition
): string => {
const prefixes = {
left: symbol,
left_space: ' ' + symbol,
right: '',
right_space: '',
};
return prefixes[ symbolPosition ] || '';
};
/**
* Get currency suffix.
*/
const getSuffix = (
// Currency symbol.
symbol: string,
// Position of currency symbol from settings.
symbolPosition: SymbolPosition
): string => {
const suffixes = {
left: '',
left_space: '',
right: symbol,
right_space: ' ' + symbol,
};
return suffixes[ symbolPosition ] || '';
};
/**
* Currency information in normalized format from server settings.
*/
const siteCurrencySettings: Currency = {
code: CURRENCY.code,
symbol: CURRENCY.symbol,
thousandSeparator: CURRENCY.thousandSeparator,
decimalSeparator: CURRENCY.decimalSeparator,
minorUnit: CURRENCY.precision,
prefix: getPrefix(
CURRENCY.symbol,
CURRENCY.symbolPosition as SymbolPosition
),
suffix: getSuffix(
CURRENCY.symbol,
CURRENCY.symbolPosition as SymbolPosition
),
};
/**
* Gets currency information in normalized format from an API response or the server.
*
@ -77,7 +21,7 @@ export const getCurrencyFromPriceResponse = (
| CartShippingPackageShippingRate
): Currency => {
if ( ! currencyData?.currency_code ) {
return siteCurrencySettings;
return SITE_CURRENCY;
}
const {
@ -91,15 +35,21 @@ export const getCurrencyFromPriceResponse = (
} = currencyData;
return {
code: code || 'USD',
symbol: symbol || '$',
code: code || SITE_CURRENCY.code,
symbol: symbol || SITE_CURRENCY.symbol,
thousandSeparator:
typeof thousandSeparator === 'string' ? thousandSeparator : ',',
typeof thousandSeparator === 'string'
? thousandSeparator
: SITE_CURRENCY.thousandSeparator,
decimalSeparator:
typeof decimalSeparator === 'string' ? decimalSeparator : '.',
minorUnit: Number.isFinite( minorUnit ) ? minorUnit : 2,
prefix: typeof prefix === 'string' ? prefix : '$',
suffix: typeof suffix === 'string' ? suffix : '',
typeof decimalSeparator === 'string'
? decimalSeparator
: SITE_CURRENCY.decimalSeparator,
minorUnit: Number.isFinite( minorUnit )
? minorUnit
: SITE_CURRENCY.minorUnit,
prefix: typeof prefix === 'string' ? prefix : SITE_CURRENCY.prefix,
suffix: typeof suffix === 'string' ? suffix : SITE_CURRENCY.suffix,
};
};
@ -110,7 +60,7 @@ export const getCurrency = (
currencyData: Partial< Currency > = {}
): Currency => {
return {
...siteCurrencySettings,
...SITE_CURRENCY,
...currencyData,
};
};

View File

@ -0,0 +1,4 @@
Significance: minor
Type: dev
In blocks codebase, export SITE_CURRENCY property with properties matching typescript definitions.