Update interactivity price filter block to use latest Interactivity Store API (https://github.com/woocommerce/woocommerce-blocks/pull/11943)
This commit is contained in:
parent
a652fa18f8
commit
58c6339ac9
|
@ -3,14 +3,15 @@
|
|||
*/
|
||||
import { store, navigate } from '@woocommerce/interactivity';
|
||||
import { formatPrice, getCurrency } from '@woocommerce/price-format';
|
||||
import { HTMLElementEvent } from '@woocommerce/types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { ActionProps, StateProps } from './types';
|
||||
import { PriceFilterState } from './types';
|
||||
|
||||
const getHrefWithFilters = ( { state }: StateProps ) => {
|
||||
const { minPrice, maxPrice } = state.filters;
|
||||
const getHrefWithFilters = ( state: PriceFilterState ) => {
|
||||
const { minPrice = 0, maxPrice = 0, maxRange = 0 } = state;
|
||||
const url = new URL( window.location.href );
|
||||
const { searchParams } = url;
|
||||
|
||||
|
@ -20,7 +21,7 @@ const getHrefWithFilters = ( { state }: StateProps ) => {
|
|||
searchParams.delete( 'min_price' );
|
||||
}
|
||||
|
||||
if ( maxPrice < state.filters.maxRange ) {
|
||||
if ( maxPrice < maxRange ) {
|
||||
searchParams.set( 'max_price', maxPrice.toString() );
|
||||
} else {
|
||||
searchParams.delete( 'max_price' );
|
||||
|
@ -33,12 +34,27 @@ const getHrefWithFilters = ( { state }: StateProps ) => {
|
|||
return url.href;
|
||||
};
|
||||
|
||||
store( {
|
||||
state: {
|
||||
filters: {
|
||||
rangeStyle: ( { state }: StateProps ) => {
|
||||
const { minPrice, maxPrice, minRange, maxRange } =
|
||||
state.filters;
|
||||
interface PriceFilterStore {
|
||||
state: PriceFilterState;
|
||||
actions: {
|
||||
setMinPrice: ( event: HTMLElementEvent< HTMLInputElement > ) => void;
|
||||
setMaxPrice: ( event: HTMLElementEvent< HTMLInputElement > ) => void;
|
||||
updateProducts: () => void;
|
||||
reset: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
const { state } = store< PriceFilterStore >(
|
||||
'woocommerce/collection-price-filter',
|
||||
{
|
||||
state: {
|
||||
get rangeStyle(): string {
|
||||
const {
|
||||
minPrice = 0,
|
||||
maxPrice = 0,
|
||||
minRange = 0,
|
||||
maxRange = 0,
|
||||
} = state;
|
||||
return [
|
||||
`--low: ${
|
||||
( 100 * ( minPrice - minRange ) ) /
|
||||
|
@ -50,48 +66,48 @@ store( {
|
|||
}%`,
|
||||
].join( ';' );
|
||||
},
|
||||
formattedMinPrice: ( { state }: StateProps ) => {
|
||||
const { minPrice } = state.filters;
|
||||
get formattedMinPrice(): string {
|
||||
const { minPrice = 0 } = state;
|
||||
return formatPrice( minPrice, getCurrency( { minorUnit: 0 } ) );
|
||||
},
|
||||
formattedMaxPrice: ( { state }: StateProps ) => {
|
||||
const { maxPrice } = state.filters;
|
||||
get formattedMaxPrice(): string {
|
||||
const { maxPrice = 0 } = state;
|
||||
return formatPrice( maxPrice, getCurrency( { minorUnit: 0 } ) );
|
||||
},
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
filters: {
|
||||
setMinPrice: ( { state, event }: ActionProps ) => {
|
||||
actions: {
|
||||
setMinPrice: ( event: HTMLElementEvent< HTMLInputElement > ) => {
|
||||
const { minRange = 0, maxPrice = 0, maxRange = 0 } = state;
|
||||
const value = parseFloat( event.target.value );
|
||||
state.filters.minPrice = Math.min(
|
||||
Number.isNaN( value ) ? state.filters.minRange : value,
|
||||
state.filters.maxRange - 1
|
||||
);
|
||||
state.filters.maxPrice = Math.max(
|
||||
state.filters.maxPrice,
|
||||
state.filters.minPrice + 1
|
||||
state.minPrice = Math.min(
|
||||
Number.isNaN( value ) ? minRange : value,
|
||||
maxRange - 1
|
||||
);
|
||||
state.maxPrice = Math.max( maxPrice, state.minPrice + 1 );
|
||||
},
|
||||
setMaxPrice: ( { state, event }: ActionProps ) => {
|
||||
setMaxPrice: ( event: HTMLElementEvent< HTMLInputElement > ) => {
|
||||
const {
|
||||
minRange = 0,
|
||||
minPrice = 0,
|
||||
maxPrice = 0,
|
||||
maxRange = 0,
|
||||
} = state;
|
||||
const value = parseFloat( event.target.value );
|
||||
state.filters.maxPrice = Math.max(
|
||||
Number.isNaN( value ) ? state.filters.maxRange : value,
|
||||
state.filters.minRange + 1
|
||||
);
|
||||
state.filters.minPrice = Math.min(
|
||||
state.filters.minPrice,
|
||||
state.filters.maxPrice - 1
|
||||
state.maxPrice = Math.max(
|
||||
Number.isNaN( value ) ? maxRange : value,
|
||||
minRange + 1
|
||||
);
|
||||
state.minPrice = Math.min( minPrice, maxPrice - 1 );
|
||||
},
|
||||
updateProductsWithPriceFilter: ( { state }: ActionProps ) => {
|
||||
navigate( getHrefWithFilters( { state } ) );
|
||||
updateProducts: () => {
|
||||
navigate( getHrefWithFilters( state ) );
|
||||
},
|
||||
reset: ( { state }: ActionProps ) => {
|
||||
state.filters.minPrice = 0;
|
||||
state.filters.maxPrice = state.filters.maxRange;
|
||||
navigate( getHrefWithFilters( { state } ) );
|
||||
reset: () => {
|
||||
const { maxRange = 0 } = state;
|
||||
state.minPrice = 0;
|
||||
state.maxPrice = maxRange;
|
||||
navigate( getHrefWithFilters( state ) );
|
||||
},
|
||||
},
|
||||
},
|
||||
} );
|
||||
}
|
||||
);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
* External dependencies
|
||||
*/
|
||||
import { BlockEditProps } from '@wordpress/blocks';
|
||||
import { HTMLElementEvent } from '@woocommerce/types';
|
||||
|
||||
export type BlockAttributes = {
|
||||
showInputFields: boolean;
|
||||
|
@ -16,24 +15,15 @@ export interface EditProps extends BlockEditProps< BlockAttributes > {
|
|||
}
|
||||
|
||||
export type PriceFilterState = {
|
||||
minPrice: number;
|
||||
maxPrice: number;
|
||||
minRange: number;
|
||||
maxRange: number;
|
||||
minPrice?: number;
|
||||
maxPrice?: number;
|
||||
minRange?: number;
|
||||
maxRange?: number;
|
||||
rangeStyle: string;
|
||||
formattedMinPrice: string;
|
||||
formattedMaxPrice: string;
|
||||
};
|
||||
|
||||
export type StateProps = {
|
||||
state: {
|
||||
filters: PriceFilterState;
|
||||
};
|
||||
};
|
||||
|
||||
export interface ActionProps extends StateProps {
|
||||
event: HTMLElementEvent< HTMLInputElement >;
|
||||
}
|
||||
|
||||
export type FilterComponentProps = BlockEditProps< BlockAttributes > & {
|
||||
collectionData: Partial< PriceFilterState >;
|
||||
};
|
||||
|
|
|
@ -44,20 +44,15 @@ final class CollectionPriceFilter extends AbstractBlock {
|
|||
$formatted_max_price = wc_price( $max_price, array( 'decimals' => 0 ) );
|
||||
|
||||
$data = array(
|
||||
'minPrice' => $min_price,
|
||||
'maxPrice' => $max_price,
|
||||
'minRange' => $min_range,
|
||||
'maxRange' => $max_range,
|
||||
'formattedMinPrice' => $formatted_min_price,
|
||||
'formattedMaxPrice' => $formatted_max_price,
|
||||
'minPrice' => $min_price,
|
||||
'maxPrice' => $max_price,
|
||||
'minRange' => $min_range,
|
||||
'maxRange' => $max_range,
|
||||
);
|
||||
|
||||
wc_store(
|
||||
array(
|
||||
'state' => array(
|
||||
'filters' => $data,
|
||||
),
|
||||
)
|
||||
wc_initial_state(
|
||||
'woocommerce/collection-price-filter',
|
||||
$data
|
||||
);
|
||||
|
||||
list (
|
||||
|
@ -75,9 +70,12 @@ final class CollectionPriceFilter extends AbstractBlock {
|
|||
$__high = 100 * ( $max_price - $min_range ) / ( $max_range - $min_range );
|
||||
$range_style = "--low: $__low%; --high: $__high%";
|
||||
|
||||
$data_directive = wp_json_encode( array( 'namespace' => 'woocommerce/collection-price-filter' ) );
|
||||
|
||||
$wrapper_attributes = get_block_wrapper_attributes(
|
||||
array(
|
||||
'class' => $show_input_fields && $inline_input ? 'inline-input' : '',
|
||||
'class' => $show_input_fields && $inline_input ? 'inline-input' : '',
|
||||
'data-wc-interactive' => $data_directive,
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -87,14 +85,15 @@ final class CollectionPriceFilter extends AbstractBlock {
|
|||
class="min"
|
||||
type="text"
|
||||
value="%d"
|
||||
data-wc-bind--value="state.filters.minPrice"
|
||||
data-wc-on--input="actions.filters.setMinPrice"
|
||||
data-wc-on--change="actions.filters.updateProductsWithPriceFilter"
|
||||
data-wc-bind--value="state.minPrice"
|
||||
data-wc-on--input="actions.setMinPrice"
|
||||
data-wc-on--change="actions.updateProducts"
|
||||
/>',
|
||||
esc_attr( $min_price )
|
||||
) : sprintf(
|
||||
'<span data-wc-text="state.filters.formattedMinPrice">%s</span>',
|
||||
esc_attr( $formatted_min_price )
|
||||
'<span data-wc-text="state.formattedMinPrice">%s</span>',
|
||||
// Not escaped, as this is HTML.
|
||||
$formatted_min_price
|
||||
);
|
||||
|
||||
$price_max = $show_input_fields ?
|
||||
|
@ -103,14 +102,15 @@ final class CollectionPriceFilter extends AbstractBlock {
|
|||
class="max"
|
||||
type="text"
|
||||
value="%d"
|
||||
data-wc-bind--value="state.filters.maxPrice"
|
||||
data-wc-on--input="actions.filters.setMaxPrice"
|
||||
data-wc-on--change="actions.filters.updateProductsWithPriceFilter"
|
||||
data-wc-bind--value="state.maxPrice"
|
||||
data-wc-on--input="actions.setMaxPrice"
|
||||
data-wc-on--change="actions.updateProducts"
|
||||
/>',
|
||||
esc_attr( $max_price )
|
||||
) : sprintf(
|
||||
'<span data-wc-text="state.filters.formattedMaxPrice">%s</span>',
|
||||
esc_attr( $formatted_max_price )
|
||||
'<span data-wc-text="state.formattedMaxPrice">%s</span>',
|
||||
// Not escaped, as this is HTML.
|
||||
$formatted_max_price
|
||||
);
|
||||
|
||||
ob_start();
|
||||
|
@ -119,7 +119,7 @@ final class CollectionPriceFilter extends AbstractBlock {
|
|||
<div
|
||||
class="range"
|
||||
style="<?php echo esc_attr( $range_style ); ?>"
|
||||
data-wc-bind--style="state.filters.rangeStyle"
|
||||
data-wc-bind--style="state.rangeStyle"
|
||||
>
|
||||
<div class="range-bar"></div>
|
||||
<input
|
||||
|
@ -128,11 +128,11 @@ final class CollectionPriceFilter extends AbstractBlock {
|
|||
min="<?php echo esc_attr( $min_range ); ?>"
|
||||
max="<?php echo esc_attr( $max_range ); ?>"
|
||||
value="<?php echo esc_attr( $min_price ); ?>"
|
||||
data-wc-bind--max="state.filters.maxRange"
|
||||
data-wc-bind--value="state.filters.minPrice"
|
||||
data-wc-class--active="state.filters.isMinActive"
|
||||
data-wc-on--input="actions.filters.setMinPrice"
|
||||
data-wc-on--change="actions.filters.updateProductsWithPriceFilter"
|
||||
data-wc-bind--max="state.maxRange"
|
||||
data-wc-bind--value="state.minPrice"
|
||||
data-wc-class--active="state.isMinActive"
|
||||
data-wc-on--input="actions.setMinPrice"
|
||||
data-wc-on--change="actions.updateProducts"
|
||||
>
|
||||
<input
|
||||
type="range"
|
||||
|
@ -140,15 +140,15 @@ final class CollectionPriceFilter extends AbstractBlock {
|
|||
min="<?php echo esc_attr( $min_range ); ?>"
|
||||
max="<?php echo esc_attr( $max_range ); ?>"
|
||||
value="<?php echo esc_attr( $max_price ); ?>"
|
||||
data-wc-bind--max="state.filters.maxRange"
|
||||
data-wc-bind--value="state.filters.maxPrice"
|
||||
data-wc-class--active="state.filters.isMaxActive"
|
||||
data-wc-on--input="actions.filters.setMaxPrice"
|
||||
data-wc-on--change="actions.filters.updateProductsWithPriceFilter"
|
||||
data-wc-bind--max="state.maxRange"
|
||||
data-wc-bind--value="state.maxPrice"
|
||||
data-wc-class--active="state.isMaxActive"
|
||||
data-wc-on--input="actions.setMaxPrice"
|
||||
data-wc-on--change="actions.updateProducts"
|
||||
>
|
||||
</div>
|
||||
<div class="text">
|
||||
<?php // $price_min and $price_max are escapsed in the sprintf() calls above. ?>
|
||||
<?php // $price_min and $price_max are escaped in the sprintf() calls above. ?>
|
||||
<?php echo $price_min; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php echo $price_max; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue