[Experimental] Price filter: fix range slider update (#50935)
* Price filter: fix range slider update * Add changefile(s) from automation for the following project(s): woocommerce-blocks, woocommerce * Fix linting error * Remove unneeded state setter * Update plugins/woocommerce-blocks/assets/js/blocks/product-filter/inner-blocks/price-filter/frontend.ts Co-authored-by: Alexandre Lara <allexandrelara@gmail.com> * Fix linting error --------- Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Alexandre Lara <allexandrelara@gmail.com>
This commit is contained in:
parent
5c58d9d50c
commit
cc07a5f902
|
@ -76,20 +76,88 @@ const debounceUpdate = debounce( ( context, element, event ) => {
|
|||
);
|
||||
}, 1000 );
|
||||
|
||||
const constrainRangeSliderValues = (
|
||||
/**
|
||||
* Tuple containing min and max values.
|
||||
*/
|
||||
values: [ number, number ],
|
||||
/**
|
||||
* Min allowed value for the sliders.
|
||||
*/
|
||||
min?: number | null,
|
||||
/**
|
||||
* Max allowed value for the sliders.
|
||||
*/
|
||||
max?: number | null,
|
||||
/**
|
||||
* Step value for the sliders.
|
||||
*/
|
||||
step = 1,
|
||||
/**
|
||||
* Whether we're currently interacting with the min range slider or not, so we update the correct values.
|
||||
*/
|
||||
isMin = false
|
||||
): { minPrice: number; maxPrice: number } => {
|
||||
let [ minValue, maxValue ] = values;
|
||||
|
||||
const isFinite = ( n: number | null | undefined ): n is number =>
|
||||
Number.isFinite( n );
|
||||
|
||||
if ( ! isFinite( minValue ) ) {
|
||||
minValue = min || 0;
|
||||
}
|
||||
|
||||
if ( ! isFinite( maxValue ) ) {
|
||||
maxValue = max || step;
|
||||
}
|
||||
|
||||
if ( isFinite( min ) && min > minValue ) {
|
||||
minValue = min;
|
||||
}
|
||||
|
||||
if ( isFinite( max ) && max <= minValue ) {
|
||||
minValue = max - step;
|
||||
}
|
||||
|
||||
if ( isFinite( min ) && min >= maxValue ) {
|
||||
maxValue = min + step;
|
||||
}
|
||||
|
||||
if ( isFinite( max ) && max < maxValue ) {
|
||||
maxValue = max;
|
||||
}
|
||||
|
||||
if ( ! isMin && minValue >= maxValue ) {
|
||||
minValue = maxValue - step;
|
||||
}
|
||||
|
||||
if ( isMin && maxValue <= minValue ) {
|
||||
maxValue = minValue + step;
|
||||
}
|
||||
|
||||
return { minPrice: minValue, maxPrice: maxValue };
|
||||
};
|
||||
|
||||
const getRangeStyle = (
|
||||
minPrice: number,
|
||||
maxPrice: number,
|
||||
minRange: number,
|
||||
maxRange: number
|
||||
) => {
|
||||
return `--low: ${
|
||||
( 100 * ( minPrice - minRange ) ) / ( maxRange - minRange )
|
||||
}%; --high: ${
|
||||
( 100 * ( maxPrice - minRange ) ) / ( maxRange - minRange )
|
||||
}%;`;
|
||||
};
|
||||
|
||||
store< PriceFilterStore >( 'woocommerce/product-filter-price', {
|
||||
state: {
|
||||
rangeStyle: () => {
|
||||
const { minPrice, maxPrice, minRange, maxRange } =
|
||||
getContext< PriceFilterContext >();
|
||||
|
||||
return [
|
||||
`--low: ${
|
||||
( 100 * ( minPrice - minRange ) ) / ( maxRange - minRange )
|
||||
}%`,
|
||||
`--high: ${
|
||||
( 100 * ( maxPrice - minRange ) ) / ( maxRange - minRange )
|
||||
}%`,
|
||||
].join( ';' );
|
||||
return getRangeStyle( minPrice, maxPrice, minRange, maxRange );
|
||||
},
|
||||
formattedMinPrice: () => {
|
||||
const { minPrice } = getContext< PriceFilterContext >();
|
||||
|
@ -126,5 +194,40 @@ store< PriceFilterStore >( 'woocommerce/product-filter-price', {
|
|||
} )
|
||||
);
|
||||
},
|
||||
updateRange: ( event: HTMLElementEvent< HTMLInputElement > ) => {
|
||||
const context = getContext< PriceFilterContext >();
|
||||
const { minPrice, maxPrice, minRange, maxRange } = context;
|
||||
const isMin = event.target.classList.contains( 'min' );
|
||||
const targetValue = Number( event.target.value );
|
||||
const stepValue = 1;
|
||||
const currentValues: [ number, number ] = isMin
|
||||
? [
|
||||
Math.round( targetValue / stepValue ) * stepValue,
|
||||
maxPrice,
|
||||
]
|
||||
: [
|
||||
minPrice,
|
||||
Math.round( targetValue / stepValue ) * stepValue,
|
||||
];
|
||||
const values = constrainRangeSliderValues(
|
||||
currentValues,
|
||||
minRange,
|
||||
maxRange,
|
||||
stepValue,
|
||||
isMin
|
||||
);
|
||||
|
||||
if ( targetValue >= maxPrice ) {
|
||||
context.maxPrice = minPrice + 1;
|
||||
} else if ( targetValue <= minPrice ) {
|
||||
context.minPrice = maxPrice - 1;
|
||||
}
|
||||
|
||||
if ( isMin ) {
|
||||
context.minPrice = values.minPrice;
|
||||
} else {
|
||||
context.maxPrice = values.maxPrice;
|
||||
}
|
||||
},
|
||||
},
|
||||
} );
|
||||
|
|
|
@ -34,5 +34,6 @@ export type PriceFilterStore = {
|
|||
updateProducts: ( event: HTMLElementEvent< HTMLInputElement > ) => void;
|
||||
selectInputContent: () => void;
|
||||
reset: () => void;
|
||||
updateRange: ( event: HTMLElementEvent< HTMLInputElement > ) => void;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: tweak
|
||||
Comment: Price slider: fix range bar styling and dynamic input
|
||||
|
|
@ -234,6 +234,7 @@ final class ProductFilterPrice extends AbstractBlock {
|
|||
data-wc-bind--max="context.maxRange"
|
||||
data-wc-bind--value="context.minPrice"
|
||||
data-wc-on--change="actions.updateProducts"
|
||||
data-wc-on--input="actions.updateRange"
|
||||
>
|
||||
<input
|
||||
type="range"
|
||||
|
@ -246,6 +247,7 @@ final class ProductFilterPrice extends AbstractBlock {
|
|||
data-wc-bind--max="context.maxRange"
|
||||
data-wc-bind--value="context.maxPrice"
|
||||
data-wc-on--change="actions.updateProducts"
|
||||
data-wc-on--input="actions.updateRange"
|
||||
>
|
||||
</div>
|
||||
<div class="wp-block-woocommerce-product-filter-price-content-right-input text">
|
||||
|
|
Loading…
Reference in New Issue