/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { useQueryStateByKey } from '@woocommerce/base-context/hooks';
import { useMemo } from '@wordpress/element';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import Label from '@woocommerce/base-components/label';
/**
* Internal dependencies
*/
import './style.scss';
import { getAttributeFromTaxonomy } from '../../utils/attributes';
import { formatPriceRange, renderRemovableListItem } from './utils';
import ActiveAttributeFilters from './active-attribute-filters';
/**
* Component displaying active filters.
*
* @param {Object} props Incoming props for the component.
* @param {Object} props.attributes Incoming attributes for the block.
* @param {boolean} props.isEditor Whether or not in the editor context.
*/
const ActiveFiltersBlock = ( {
attributes: blockAttributes,
isEditor = false,
} ) => {
const [ productAttributes, setProductAttributes ] = useQueryStateByKey(
'attributes',
[]
);
const [ minPrice, setMinPrice ] = useQueryStateByKey( 'min_price' );
const [ maxPrice, setMaxPrice ] = useQueryStateByKey( 'max_price' );
const activePriceFilters = useMemo( () => {
if ( ! Number.isFinite( minPrice ) && ! Number.isFinite( maxPrice ) ) {
return null;
}
return renderRemovableListItem( {
type: __( 'Price', 'woocommerce' ),
name: formatPriceRange( minPrice, maxPrice ),
removeCallback: () => {
setMinPrice( undefined );
setMaxPrice( undefined );
},
displayStyle: blockAttributes.displayStyle,
} );
}, [
minPrice,
maxPrice,
blockAttributes.displayStyle,
setMinPrice,
setMaxPrice,
] );
const activeAttributeFilters = useMemo( () => {
return productAttributes.map( ( attribute ) => {
const attributeObject = getAttributeFromTaxonomy(
attribute.attribute
);
return (
<ActiveAttributeFilters
attributeObject={ attributeObject }
displayStyle={ blockAttributes.displayStyle }
slugs={ attribute.slug }
key={ attribute.attribute }
operator={ attribute.operator }
/>
);
} );
}, [ productAttributes, blockAttributes.displayStyle ] );
const hasFilters = () => {
return (
productAttributes.length > 0 ||
Number.isFinite( minPrice ) ||
Number.isFinite( maxPrice )
);
};
if ( ! hasFilters() && ! isEditor ) {
return null;
}
const TagName = `h${ blockAttributes.headingLevel }`;
const listClasses = classnames( 'wc-block-active-filters__list', {
'wc-block-active-filters__list--chips':
blockAttributes.displayStyle === 'chips',
} );
return (
<>
{ ! isEditor && blockAttributes.heading && (
<TagName>{ blockAttributes.heading }</TagName>
) }
<div className="wc-block-active-filters">
<ul className={ listClasses }>
{ isEditor ? (
<>
{ renderRemovableListItem( {
type: __(
'Size',
'woocommerce'
),
name: __(
'Small',
'woocommerce'
),
displayStyle: blockAttributes.displayStyle,
} ) }
{ renderRemovableListItem( {
type: __(
'Color',
'woocommerce'
),
name: __(
'Blue',
'woocommerce'
),
displayStyle: blockAttributes.displayStyle,
} ) }
</>
) : (
<>
{ activePriceFilters }
{ activeAttributeFilters }
</>
) }
</ul>
<button
className="wc-block-active-filters__clear-all"
onClick={ () => {
setMinPrice( undefined );
setMaxPrice( undefined );
setProductAttributes( [] );
} }
>
<Label
label={ __(
'Clear All',
'woocommerce'
) }
screenReaderLabel={ __(
'Clear All Filters',
'woocommerce'
) }
/>
</button>
</div>
</>
);
};
ActiveFiltersBlock.propTypes = {
/**
* The attributes for this block.
*/
attributes: PropTypes.object.isRequired,
/**
* Whether it's in the editor or frontend display.
*/
isEditor: PropTypes.bool,
};
export default ActiveFiltersBlock;