* Price filter: allow any numeric input in inputs

* Price filter: allow negative numbers in input fields (https://github.com/woocommerce/woocommerce-blocks/pull/1458)

* Price filter: allow negative numbers in input fields

* Always update input fields based on minPrice and maxPrice

* Don't default values to 0
This commit is contained in:
Albert Juhé Lluveras 2020-01-02 14:07:59 +01:00 committed by GitHub
parent 03bfa7d5a5
commit 5701f7d6c9
5 changed files with 77 additions and 24 deletions

View File

@ -35,7 +35,7 @@ const FormattedMonetaryAmount = ( {
} ) => {
const priceValue = value / 10 ** currency.minorUnit;
if ( ! Number.isFinite( priceValue ) ) {
if ( ! Number.isFinite( priceValue ) && priceValue === '-' ) {
return null;
}

View File

@ -8,23 +8,37 @@
* @param {boolean} isMin Whether we're currently interacting with the min range slider or not, so we update the correct values.
* @return {Array} Validated and updated min/max values that fit within the range slider constraints.
*/
export const constrainRangeSliderValues = ( values, min, max, step, isMin ) => {
let minValue = parseInt( values[ 0 ], 10 ) || min;
let maxValue = parseInt( values[ 1 ], 10 ) || step; // Max should be one step above min if invalid or 0.
export const constrainRangeSliderValues = (
values,
min,
max,
step = 1,
isMin = false
) => {
let minValue = parseInt( values[ 0 ], 10 );
let maxValue = parseInt( values[ 1 ], 10 );
if ( min > minValue ) {
if ( ! Number.isFinite( minValue ) ) {
minValue = min || 0;
}
if ( ! Number.isFinite( maxValue ) ) {
maxValue = max || step;
}
if ( Number.isFinite( min ) && min > minValue ) {
minValue = min;
}
if ( max <= minValue ) {
if ( Number.isFinite( max ) && max <= minValue ) {
minValue = max - step;
}
if ( min >= maxValue ) {
if ( Number.isFinite( min ) && min >= maxValue ) {
maxValue = min + step;
}
if ( max < maxValue ) {
if ( Number.isFinite( max ) && max < maxValue ) {
maxValue = max;
}

View File

@ -18,7 +18,7 @@ import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-mone
* Internal dependencies
*/
import './style.scss';
import { constrainRangeSliderValues } from './utils';
import { constrainRangeSliderValues } from './constrain-range-slider-values';
import FilterSubmitButton from '../filter-submit-button';
/**
@ -200,8 +200,8 @@ const PriceSlider = ( {
);
const values = constrainRangeSliderValues(
[ minPriceInput, maxPriceInput ],
minConstraint,
maxConstraint,
null,
null,
stepValue,
isMin
);
@ -253,7 +253,11 @@ const PriceSlider = ( {
'Filter products by minimum price',
'woo-gutenberg-products-block'
) }
value={ minPrice || 0 }
value={
Number.isFinite( minPrice )
? minPrice
: minConstraint
}
onChange={ rangeInputOnChange }
step={ minRangeStep }
min={ minConstraint }
@ -268,7 +272,11 @@ const PriceSlider = ( {
'Filter products by maximum price',
'woo-gutenberg-products-block'
) }
value={ maxPrice || 0 }
value={
Number.isFinite( maxPrice )
? maxPrice
: maxConstraint
}
onChange={ rangeInputOnChange }
step={ maxRangeStep }
min={ minConstraint }

View File

@ -0,0 +1,39 @@
/**
* Internal dependencies
*/
import { constrainRangeSliderValues } from '../constrain-range-slider-values';
describe( 'constrainRangeSliderValues', () => {
test.each`
values | min | max | step | isMin | expected
${[ 20, 60 ]} | ${0} | ${70} | ${10} | ${true} | ${[ 20, 60 ]}
${[ 20, 60 ]} | ${20} | ${60} | ${10} | ${true} | ${[ 20, 60 ]}
${[ 20, 60 ]} | ${30} | ${50} | ${10} | ${true} | ${[ 30, 50 ]}
${[ 50, 50 ]} | ${20} | ${60} | ${10} | ${true} | ${[ 50, 60 ]}
${[ 50, 50 ]} | ${20} | ${60} | ${10} | ${false} | ${[ 40, 50 ]}
${[ 20, 60 ]} | ${null} | ${null} | ${10} | ${true} | ${[ 20, 60 ]}
${[ null, null ]} | ${20} | ${60} | ${10} | ${true} | ${[ 20, 60 ]}
${[ '20', '60' ]} | ${30} | ${50} | ${10} | ${true} | ${[ 30, 50 ]}
${[ -60, -20 ]} | ${-70} | ${0} | ${10} | ${true} | ${[ -60, -20 ]}
${[ -60, -20 ]} | ${-60} | ${-20} | ${10} | ${true} | ${[ -60, -20 ]}
${[ -60, -20 ]} | ${-50} | ${-30} | ${10} | ${true} | ${[ -50, -30 ]}
${[ -50, -50 ]} | ${-60} | ${-20} | ${10} | ${true} | ${[ -50, -40 ]}
${[ -50, -50 ]} | ${-60} | ${-20} | ${10} | ${false} | ${[ -60, -50 ]}
${[ -60, -20 ]} | ${null} | ${null} | ${10} | ${true} | ${[ -60, -20 ]}
${[ null, null ]} | ${-60} | ${-20} | ${10} | ${true} | ${[ -60, -20 ]}
${[ '-60', '-20' ]} | ${-50} | ${-30} | ${10} | ${true} | ${[ -50, -30 ]}
`(
`correctly sets prices to its constraints with arguments values: $values, min: $min, max: $max, step: $step and isMin: $isMin`,
( { values, min, max, step, isMin, expected } ) => {
const constrainedValues = constrainRangeSliderValues(
values,
min,
max,
step,
isMin
);
expect( constrainedValues ).toEqual( expected );
}
);
} );

View File

@ -61,7 +61,7 @@ const PriceFilterBlock = ( { attributes, isEditor = false } ) => {
setMaxPriceQuery( maxPrice === maxConstraint ? undefined : maxPrice );
}, [ minPrice, maxPrice, minConstraint, maxConstraint ] );
// Callback when slider is changed.
// Callback when slider or input fields are changed.
const onChange = useCallback(
( prices ) => {
if ( prices[ 0 ] !== minPrice ) {
@ -105,14 +105,6 @@ const PriceFilterBlock = ( { attributes, isEditor = false } ) => {
}
const TagName = `h${ attributes.headingLevel }`;
const min = Math.max(
Number.isFinite( minPrice ) ? minPrice : -Infinity,
Number.isFinite( minConstraint ) ? minConstraint : -Infinity
);
const max = Math.min(
Number.isFinite( maxPrice ) ? maxPrice : Infinity,
Number.isFinite( maxConstraint ) ? maxConstraint : Infinity
);
return (
<Fragment>
@ -123,8 +115,8 @@ const PriceFilterBlock = ( { attributes, isEditor = false } ) => {
<PriceSlider
minConstraint={ minConstraint }
maxConstraint={ maxConstraint }
minPrice={ min }
maxPrice={ max }
minPrice={ minPrice }
maxPrice={ maxPrice }
currency={ currency }
showInputFields={ attributes.showInputFields }
showFilterButton={ attributes.showFilterButton }