Skip to content

Commit

Permalink
Add: Active Filters block powered by Interactivity API (#42008)
Browse files Browse the repository at this point in the history
* add: active filters block

* update text domain

* chore: linting

* use template string instead of concat

* add experimental flag to register block type calls

* chore: update comments

* feat: register active rating filter data

* fix: unique navigation id when collection filters are added outside product collection

* fix: active filter rating id

* fix: return the href

* chore: phpcs
  • Loading branch information
dinhtungdu committed Dec 19, 2023
1 parent 1965dfb commit c651b10
Show file tree
Hide file tree
Showing 29 changed files with 1,158 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"reusable": false
},
"usesContext": [
"query"
"query",
"queryId"
],
"providesContext": {
"collectionData": "collectionData"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { AttributeSetting } from '@woocommerce/types';
const ATTRIBUTES = getSetting< AttributeSetting[] >( 'attributes', [] );

const template = [
[ 'woocommerce/collection-active-filters', {} ],
[
'core/heading',
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"name": "woocommerce/collection-active-filters",
"version": "1.0.0",
"title": "Collection Active Filters",
"description": "Display the currently active filters.",
"category": "woocommerce",
"keywords": [
"WooCommerce"
],
"textdomain": "woocommerce",
"apiVersion": 2,
"ancestor": [
"woocommerce/collection-filters"
],
"supports": {
"interactivity": true
},
"usesContext": [
"queryId"
],
"attributes": {
"displayStyle": {
"type": "string",
"default": "list"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* External dependencies
*/
import { InspectorControls } from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import {
PanelBody,
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
__experimentalToggleGroupControl as ToggleGroupControl,
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
} from '@wordpress/components';

/**
* Internal dependencies
*/
import type { EditProps, BlockAttributes } from '../types';

export const Inspector = ( { attributes, setAttributes }: EditProps ) => {
const { displayStyle } = attributes;

return (
<InspectorControls>
<PanelBody title={ __( 'Display Settings', 'woocommerce' ) }>
<ToggleGroupControl
label={ __( 'Display Style', 'woocommerce' ) }
value={ displayStyle }
onChange={ ( value: BlockAttributes[ 'displayStyle' ] ) =>
setAttributes( {
displayStyle: value,
} )
}
className="wc-block-active-filter__style-toggle"
>
<ToggleGroupControlOption
value="list"
label={ __( 'List', 'woocommerce' ) }
/>
<ToggleGroupControlOption
value="chips"
label={ __( 'Chips', 'woocommerce' ) }
/>
</ToggleGroupControl>
</PanelBody>
</InspectorControls>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { Label, RemovableChip } from '@woocommerce/blocks-components';
import { Icon, closeSmall } from '@wordpress/icons';

interface RemovableListItemProps {
type: string;
name: string;
prefix?: string | JSX.Element;
showLabel?: boolean;
isLoading?: boolean;
displayStyle: string;
removeCallback?: () => void;
}

export const RemovableListItem = ( {
type,
name,
prefix = '',
removeCallback = () => null,
showLabel = true,
displayStyle,
}: RemovableListItemProps ) => {
const prefixedName = prefix ? (
<>
{ prefix }
&nbsp;
{ name }
</>
) : (
name
);
const removeText = sprintf(
/* translators: %s attribute value used in the filter. For example: yellow, green, small, large. */
__( 'Remove %s filter', 'woocommerce' ),
name
);

return (
<li
className="wc-block-active-filters__list-item"
key={ `${ type }: ${ name }` }
>
{ showLabel && (
<span className="wc-block-active-filters__list-item-type">
{ `${ type }: ` }
</span>
) }
{ displayStyle === 'chips' ? (
<RemovableChip
element="span"
text={ prefixedName }
onRemove={ removeCallback }
radius="large"
ariaLabel={ removeText }
/>
) : (
<span className="wc-block-active-filters__list-item-name">
<button
className="wc-block-active-filters__list-item-remove"
onClick={ removeCallback }
>
<Icon
className="wc-block-components-chip__remove-icon"
icon={ closeSmall }
size={ 16 }
/>
<Label screenReaderLabel={ removeText } />
</button>
{ prefixedName }
</span>
) }
</li>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import classNames from 'classnames';
import { Disabled } from '@wordpress/components';

/**
* Internal dependencies
*/
import { EditProps } from './types';
import { Inspector } from './components/inspector';
import { RemovableListItem } from './components/removable-list-item';

const Edit = ( props: EditProps ) => {
const { displayStyle } = props.attributes;

const blockProps = useBlockProps( {
className: 'wc-block-active-filters',
} );

return (
<div { ...blockProps }>
<Inspector { ...props } />
<Disabled>
<ul
className={ classNames( 'wc-block-active-filters__list', {
'wc-block-active-filters__list--chips':
displayStyle === 'chips',
} ) }
>
<RemovableListItem
type={ __( 'Size', 'woocommerce' ) }
name={ __( 'Small', 'woocommerce' ) }
displayStyle={ displayStyle }
/>
<RemovableListItem
type={ __( 'Color', 'woocommerce' ) }
name={ __( 'Blue', 'woocommerce' ) }
displayStyle={ displayStyle }
/>
</ul>
</Disabled>
</div>
);
};

export default Edit;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* External dependencies
*/
import { store, navigate, getContext } from '@woocommerce/interactivity';

type ActiveFiltersContext = {
queryId: number;
params: string[];
};

store( 'woocommerce/collection-active-filters', {
actions: {
clearAll: () => {
const { params } = getContext< ActiveFiltersContext >();
const url = new URL( window.location.href );
const { searchParams } = url;

params.forEach( ( param ) => searchParams.delete( param ) );
navigate( url.href );
},
},
} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* External dependencies
*/
import { registerBlockType } from '@wordpress/blocks';
import { Icon } from '@wordpress/icons';
import { toggle } from '@woocommerce/icons';
import { isExperimentalBuild } from '@woocommerce/block-settings';

/**
* Internal dependencies
*/
import metadata from './block.json';
import Edit from './edit';
import './style.scss';

if ( isExperimentalBuild() ) {
registerBlockType( metadata, {
icon: {
src: (
<Icon
icon={ toggle }
className="wc-block-editor-components-block-icon"
/>
),
},
edit: Edit,
} );
}

0 comments on commit c651b10

Please sign in to comment.