diff --git a/plugins/woocommerce-blocks/assets/js/base/components/price-slider/index.js b/plugins/woocommerce-blocks/assets/js/base/components/price-slider/index.js
index ff51876c6ca..ee75eaffdb4 100644
--- a/plugins/woocommerce-blocks/assets/js/base/components/price-slider/index.js
+++ b/plugins/woocommerce-blocks/assets/js/base/components/price-slider/index.js
@@ -262,7 +262,7 @@ const PriceSlider = ( {
onMouseMove={ findClosestRange }
onFocus={ findClosestRange }
>
- { ! isLoading && hasValidConstraints && (
+ { hasValidConstraints && (
) }
diff --git a/plugins/woocommerce-blocks/assets/js/base/utils/price.js b/plugins/woocommerce-blocks/assets/js/base/utils/price.js
index 1798a22e01d..cf7fc8ec17f 100644
--- a/plugins/woocommerce-blocks/assets/js/base/utils/price.js
+++ b/plugins/woocommerce-blocks/assets/js/base/utils/price.js
@@ -9,17 +9,17 @@ import { CURRENCY } from '@woocommerce/settings';
*
* @param {number} value Number to format.
* @param {string} priceFormat Price format string.
- * @param {string} currencySymbol Curency symbol.
+ * @param {string} currencySymbol Currency symbol.
*/
export const formatPrice = (
value,
priceFormat = CURRENCY.price_format,
currencySymbol = CURRENCY.symbol
) => {
- if ( value === '' || undefined === value ) {
+ const formattedNumber = parseInt( value, 10 );
+ if ( ! isFinite( formattedNumber ) ) {
return '';
}
- const formattedNumber = parseInt( value, 10 );
const formattedValue = sprintf(
priceFormat,
currencySymbol,
diff --git a/plugins/woocommerce-blocks/assets/js/base/utils/test/price.js b/plugins/woocommerce-blocks/assets/js/base/utils/test/price.js
new file mode 100644
index 00000000000..f1ae8752677
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/base/utils/test/price.js
@@ -0,0 +1,29 @@
+/**
+ * Internal dependencies
+ */
+import { formatPrice } from '../price';
+
+describe( 'formatPrice', () => {
+ test.each`
+ value | priceFormat | currencySymbol | expected
+ ${10} | ${'%1$s%2$s'} | ${'€'} | ${'€10'}
+ ${10} | ${'%2$s%1$s'} | ${'€'} | ${'10€'}
+ ${10} | ${'%2$s%1$s'} | ${'$'} | ${'10$'}
+ ${'10'} | ${'%1$s%2$s'} | ${'€'} | ${'€10'}
+ ${0} | ${'%1$s%2$s'} | ${'€'} | ${'€0'}
+ ${''} | ${'%1$s%2$s'} | ${'€'} | ${''}
+ ${null} | ${'%1$s%2$s'} | ${'€'} | ${''}
+ ${undefined} | ${'%1$s%2$s'} | ${'€'} | ${''}
+ `(
+ 'correctly formats price given "$value", "$priceFormat", and "$currencySymbol"',
+ ( { value, priceFormat, currencySymbol, expected } ) => {
+ const formattedPrice = formatPrice(
+ value,
+ priceFormat,
+ currencySymbol
+ );
+
+ expect( formattedPrice ).toEqual( expected );
+ }
+ );
+} );
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/price-filter/block.js b/plugins/woocommerce-blocks/assets/js/blocks/price-filter/block.js
index f6f74200f19..09bbe6b5996 100644
--- a/plugins/woocommerce-blocks/assets/js/blocks/price-filter/block.js
+++ b/plugins/woocommerce-blocks/assets/js/blocks/price-filter/block.js
@@ -12,6 +12,11 @@ import { CURRENCY } from '@woocommerce/settings';
import { useDebouncedCallback } from 'use-debounce';
import PropTypes from 'prop-types';
+/**
+ * Internal dependencies
+ */
+import usePriceConstraints from './use-price-constraints.js';
+
/**
* Component displaying a price filter.
*/
@@ -31,12 +36,10 @@ const PriceFilterBlock = ( { attributes, isEditor = false } ) => {
const [ minPrice, setMinPrice ] = useState();
const [ maxPrice, setMaxPrice ] = useState();
- const minConstraint = isNaN( results.min_price )
- ? null
- : Math.floor( parseInt( results.min_price, 10 ) / 10 ) * 10;
- const maxConstraint = isNaN( results.max_price )
- ? null
- : Math.ceil( parseInt( results.max_price, 10 ) / 10 ) * 10;
+ const { minConstraint, maxConstraint } = usePriceConstraints( {
+ minPrice: results.min_price,
+ maxPrice: results.max_price,
+ } );
// Updates the query after a short delay.
const [ debouncedUpdateQuery ] = useDebouncedCallback( () => {
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/price-filter/test/use-price-constraints.js b/plugins/woocommerce-blocks/assets/js/blocks/price-filter/test/use-price-constraints.js
new file mode 100644
index 00000000000..499ba04893e
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/blocks/price-filter/test/use-price-constraints.js
@@ -0,0 +1,38 @@
+/**
+ * External dependencies
+ */
+import TestRenderer from 'react-test-renderer';
+
+/**
+ * Internal dependencies
+ */
+import { usePriceConstraint } from '../use-price-constraints';
+
+describe( 'usePriceConstraints', () => {
+ const TestComponent = ( { price } ) => {
+ const priceConstraint = usePriceConstraint( price );
+ return
;
+ };
+
+ it( 'price constraint should be updated when new price is set', () => {
+ const renderer = TestRenderer.create( );
+ const container = renderer.root.findByType( 'div' );
+
+ expect( container.props.priceConstraint ).toBe( 10 );
+
+ renderer.update( );
+
+ expect( container.props.priceConstraint ).toBe( 20 );
+ } );
+
+ it( 'previous price constraint should be preserved when new price is not a infinite number', () => {
+ const renderer = TestRenderer.create( );
+ const container = renderer.root.findByType( 'div' );
+
+ expect( container.props.priceConstraint ).toBe( 10 );
+
+ renderer.update( );
+
+ expect( container.props.priceConstraint ).toBe( 10 );
+ } );
+} );
diff --git a/plugins/woocommerce-blocks/assets/js/blocks/price-filter/use-price-constraints.js b/plugins/woocommerce-blocks/assets/js/blocks/price-filter/use-price-constraints.js
new file mode 100644
index 00000000000..bff8a4103bd
--- /dev/null
+++ b/plugins/woocommerce-blocks/assets/js/blocks/price-filter/use-price-constraints.js
@@ -0,0 +1,23 @@
+/**
+ * External dependencies
+ */
+import { usePrevious } from '@woocommerce/base-hooks';
+
+export const usePriceConstraint = ( price ) => {
+ const currentConstraint = isNaN( price )
+ ? null
+ : Math.floor( parseInt( price, 10 ) / 10 ) * 10;
+ const previousConstraint = usePrevious( currentConstraint, ( val ) =>
+ Number.isFinite( val )
+ );
+ return Number.isFinite( currentConstraint )
+ ? currentConstraint
+ : previousConstraint;
+};
+
+export default ( { minPrice, maxPrice } ) => {
+ return {
+ minConstraint: usePriceConstraint( minPrice ),
+ maxConstraint: usePriceConstraint( maxPrice ),
+ };
+};
diff --git a/plugins/woocommerce-blocks/tests/js/jest.config.json b/plugins/woocommerce-blocks/tests/js/jest.config.json
index 5f21d40bd0c..31c268ecfa8 100644
--- a/plugins/woocommerce-blocks/tests/js/jest.config.json
+++ b/plugins/woocommerce-blocks/tests/js/jest.config.json
@@ -15,6 +15,7 @@
"@woocommerce/base-components(.*)$": "assets/js/base/components/$1",
"@woocommerce/base-context(.*)$": "assets/js/base/context/$1",
"@woocommerce/base-hocs(.*)$": "assets/js/base/hocs/$1",
+ "@woocommerce/base-hooks(.*)$": "assets/js/base/hooks/$1",
"@woocommerce/block-data": "assets/js/data"
},
"setupFiles": [