[Experimental] Product Filter - Reintroduce Wrapper Block (#43688)
This commit is contained in:
parent
9b7d9ce689
commit
42e77d4938
|
@ -8,7 +8,7 @@ import { isExperimentalBuild } from '@woocommerce/block-settings';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { EditProps } from './types';
|
||||
import Upgrade from '../product-filters/components/upgrade';
|
||||
import Upgrade from '../product-filter/components/upgrade';
|
||||
|
||||
const Edit = ( { attributes, clientId }: EditProps ) => {
|
||||
const blockProps = useBlockProps();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "woocommerce/product-filters",
|
||||
"name": "woocommerce/product-filter",
|
||||
"version": "1.0.0",
|
||||
"title": "Product Filters",
|
||||
"title": "Product Filter",
|
||||
"description": "A block that adds product filters to the product collection.",
|
||||
"category": "woocommerce",
|
||||
"keywords": [ "WooCommerce", "Filters" ],
|
||||
|
@ -15,12 +15,15 @@
|
|||
"collectionData": "collectionData"
|
||||
},
|
||||
"attributes": {
|
||||
"filterType": {
|
||||
"type": "string"
|
||||
},
|
||||
"heading": {
|
||||
"type": "string"
|
||||
},
|
||||
"collectionData": {
|
||||
"type": "object",
|
||||
"default": {}
|
||||
},
|
||||
"filterType": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"apiVersion": 2,
|
|
@ -10,9 +10,15 @@ import { createBlock, BlockInstance } from '@wordpress/blocks';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { UPGRADE_MAP } from './upgrade';
|
||||
import { FilterType } from '../types';
|
||||
|
||||
const Downgrade = ( { clientId }: { clientId: string } ) => {
|
||||
const Downgrade = ( {
|
||||
clientId,
|
||||
filterType,
|
||||
}: {
|
||||
clientId: string;
|
||||
filterType: FilterType;
|
||||
} ) => {
|
||||
const { replaceBlock } = useDispatch( 'core/block-editor' );
|
||||
const block = useSelect( ( select ) => {
|
||||
return select( 'core/block-editor' ).getBlock( clientId );
|
||||
|
@ -20,29 +26,32 @@ const Downgrade = ( { clientId }: { clientId: string } ) => {
|
|||
|
||||
const downgradeBlock = () => {
|
||||
if ( ! block ) return;
|
||||
const filterBlock = block.innerBlocks[ 0 ];
|
||||
const filterType = Object.entries( UPGRADE_MAP ).find(
|
||||
( [ , value ] ) => value === filterBlock.name
|
||||
)?.[ 0 ];
|
||||
|
||||
if ( ! filterType ) return;
|
||||
const filterBlock = block.innerBlocks.find( ( item ) =>
|
||||
item.name.includes( 'filter' )
|
||||
);
|
||||
|
||||
const innerBlocks: BlockInstance[] = [
|
||||
createBlock( `woocommerce/${ filterType }`, {
|
||||
...filterBlock.attributes,
|
||||
heading: '',
|
||||
} ),
|
||||
];
|
||||
const headingBlock = filterBlock.innerBlocks.find(
|
||||
if ( ! filterBlock ) return;
|
||||
|
||||
const headingBlock = block.innerBlocks.find(
|
||||
( item ) => item.name === 'core/heading'
|
||||
);
|
||||
|
||||
const innerBlocks: BlockInstance[] = [];
|
||||
|
||||
if ( headingBlock ) {
|
||||
innerBlocks.unshift(
|
||||
innerBlocks.push(
|
||||
createBlock( 'core/heading', headingBlock.attributes )
|
||||
);
|
||||
}
|
||||
|
||||
innerBlocks.push(
|
||||
createBlock( `woocommerce/${ filterType }`, {
|
||||
...filterBlock.attributes,
|
||||
heading: '',
|
||||
} )
|
||||
);
|
||||
|
||||
replaceBlock(
|
||||
clientId,
|
||||
createBlock(
|
||||
|
@ -53,8 +62,6 @@ const Downgrade = ( { clientId }: { clientId: string } ) => {
|
|||
);
|
||||
};
|
||||
|
||||
if ( block?.innerBlocks.length !== 1 ) return null;
|
||||
|
||||
return (
|
||||
<InspectorControls key="inspector">
|
||||
<PanelBody title={ __( 'Legacy Block', 'woocommerce' ) }>
|
|
@ -19,15 +19,6 @@ import {
|
|||
*/
|
||||
import { FilterType } from '../types';
|
||||
|
||||
export const UPGRADE_MAP: Record< FilterType, string > = {
|
||||
'active-filters': 'woocommerce/product-filters-active',
|
||||
'price-filter': 'woocommerce/product-filters-price',
|
||||
'stock-filter': 'woocommerce/product-filters-stock-status',
|
||||
'rating-filter': 'woocommerce/product-filters-rating',
|
||||
'product-filters': 'woocommerce/product-filters',
|
||||
'attribute-filter': 'woocommerce/product-filters-attribute',
|
||||
};
|
||||
|
||||
const Upgrade = ( { clientId }: { clientId: string } ) => {
|
||||
const block = useSelect( ( select ) => {
|
||||
return select( 'core/block-editor' ).getBlock( clientId );
|
||||
|
@ -49,20 +40,11 @@ const Upgrade = ( { clientId }: { clientId: string } ) => {
|
|||
|
||||
replaceBlock(
|
||||
clientId,
|
||||
createBlock( `woocommerce/product-filters`, {}, [
|
||||
createBlock(
|
||||
`${ UPGRADE_MAP[ filterType ] }`,
|
||||
filterBlockAttributes,
|
||||
headingBlock
|
||||
? [
|
||||
createBlock(
|
||||
'core/heading',
|
||||
headingBlock.attributes
|
||||
),
|
||||
]
|
||||
: []
|
||||
),
|
||||
] )
|
||||
createBlock( 'woocommerce/product-filter', {
|
||||
...filterBlockAttributes,
|
||||
heading: headingBlock?.attributes.content || '',
|
||||
filterType,
|
||||
} )
|
||||
);
|
||||
}, [ block, clientId, replaceBlock ] );
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
|
||||
import { BlockEditProps } from '@wordpress/blocks';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import Downgrade from './components/downgrade';
|
||||
import Warning from './components/warning';
|
||||
import './editor.scss';
|
||||
import { getAllowedBlocks } from './utils';
|
||||
|
||||
const BLOCK_NAME_MAP = {
|
||||
'active-filters': 'woocommerce/product-filter-active',
|
||||
'price-filter': 'woocommerce/product-filter-price',
|
||||
'stock-filter': 'woocommerce/product-filter-stock-status',
|
||||
'rating-filter': 'woocommerce/product-filter-rating',
|
||||
'attribute-filter': 'woocommerce/product-filter-attribute',
|
||||
};
|
||||
|
||||
type FilterType = keyof typeof BLOCK_NAME_MAP;
|
||||
|
||||
const Edit = ( {
|
||||
attributes,
|
||||
clientId,
|
||||
}: BlockEditProps< { heading: string; filterType: FilterType } > ) => {
|
||||
const blockProps = useBlockProps();
|
||||
|
||||
const isNested = useSelect( ( select ) => {
|
||||
const { getBlockParentsByBlockName } = select( 'core/block-editor' );
|
||||
return !! getBlockParentsByBlockName(
|
||||
clientId,
|
||||
'woocommerce/product-collection'
|
||||
).length;
|
||||
} );
|
||||
|
||||
return (
|
||||
<nav { ...blockProps }>
|
||||
{ ! isNested && <Warning /> }
|
||||
<Downgrade
|
||||
filterType={ attributes.filterType }
|
||||
clientId={ clientId }
|
||||
/>
|
||||
<InnerBlocks
|
||||
allowedBlocks={ getAllowedBlocks( [
|
||||
...Object.values( BLOCK_NAME_MAP ),
|
||||
'woocommerce/product-filter',
|
||||
'woocommerce/filter-wrapper',
|
||||
'woocommerce/product-collection',
|
||||
'core/query',
|
||||
] ) }
|
||||
template={ [
|
||||
[
|
||||
'core/heading',
|
||||
{ level: 3, content: attributes.heading || '' },
|
||||
],
|
||||
[
|
||||
BLOCK_NAME_MAP[ attributes.filterType ],
|
||||
{
|
||||
lock: {
|
||||
remove: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
] }
|
||||
/>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Edit;
|
|
@ -31,35 +31,18 @@ if ( isExperimentalBuild() ) {
|
|||
/>
|
||||
),
|
||||
},
|
||||
edit,
|
||||
save,
|
||||
variations: [
|
||||
{
|
||||
name: 'woocommerce/product-filters-wrapper',
|
||||
title: __( 'Product Filters', 'woocommerce' ),
|
||||
description: __(
|
||||
'Enable customers to filter the product collection.',
|
||||
'woocommerce'
|
||||
),
|
||||
attributes: {
|
||||
filterType: 'product-filters',
|
||||
},
|
||||
icon: {
|
||||
src: (
|
||||
<Icon
|
||||
icon={ more }
|
||||
className="wc-block-editor-components-block-icon"
|
||||
/>
|
||||
),
|
||||
},
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: 'woocommerce/product-filters-active-wrapper',
|
||||
title: __( 'Product Filters: Active Filters', 'woocommerce' ),
|
||||
name: 'product-filter-active',
|
||||
title: __( 'Product Filter: Active Filters', 'woocommerce' ),
|
||||
description: __(
|
||||
'Display the currently active filters.',
|
||||
'woocommerce'
|
||||
),
|
||||
attributes: {
|
||||
heading: __( 'Active filters', 'woocommerce' ),
|
||||
filterType: 'active-filters',
|
||||
},
|
||||
icon: {
|
||||
|
@ -70,17 +53,18 @@ if ( isExperimentalBuild() ) {
|
|||
/>
|
||||
),
|
||||
},
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
name: 'woocommerce/product-filters-price-wrapper',
|
||||
title: __( 'Product Filters: Price', 'woocommerce' ),
|
||||
name: 'product-filter-price',
|
||||
title: __( 'Product Filter: Price', 'woocommerce' ),
|
||||
description: __(
|
||||
'Enable customers to filter the product collection by choosing a price range.',
|
||||
'woocommerce'
|
||||
),
|
||||
attributes: {
|
||||
filterType: 'price-filter',
|
||||
heading: __( 'Filter by price', 'woocommerce' ),
|
||||
heading: __( 'Filter by Price', 'woocommerce' ),
|
||||
},
|
||||
icon: {
|
||||
src: (
|
||||
|
@ -92,14 +76,15 @@ if ( isExperimentalBuild() ) {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: 'woocommerce/product-filters-stock-status-wrapper',
|
||||
title: __( 'Product Filters: Stock Status', 'woocommerce' ),
|
||||
name: 'product-filter-stock-status',
|
||||
title: __( 'Product Filter: Stock Status', 'woocommerce' ),
|
||||
description: __(
|
||||
'Enable customers to filter the product collection by stock status.',
|
||||
'woocommerce'
|
||||
),
|
||||
attributes: {
|
||||
filterType: 'stock-filter',
|
||||
heading: __( 'Filter by Stock Status', 'woocommerce' ),
|
||||
},
|
||||
icon: {
|
||||
src: (
|
||||
|
@ -111,14 +96,15 @@ if ( isExperimentalBuild() ) {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: 'woocommerce/product-filters-attribute-wrapper',
|
||||
title: __( 'Product Filters: Attribute', 'woocommerce' ),
|
||||
name: 'product-filter-attribute',
|
||||
title: __( 'Product Filter: Attribute', 'woocommerce' ),
|
||||
description: __(
|
||||
'Enable customers to filter the product collection by selecting one or more attributes, such as color.',
|
||||
'woocommerce'
|
||||
),
|
||||
attributes: {
|
||||
filterType: 'attribute-filter',
|
||||
heading: __( 'Filter by Attribute', 'woocommerce' ),
|
||||
},
|
||||
icon: {
|
||||
src: (
|
||||
|
@ -130,14 +116,15 @@ if ( isExperimentalBuild() ) {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: 'woocommerce/product-filters-rating-wrapper',
|
||||
title: __( 'Product Filters: Rating', 'woocommerce' ),
|
||||
name: 'product-filter-rating',
|
||||
title: __( 'Product Filter: Rating', 'woocommerce' ),
|
||||
description: __(
|
||||
'Enable customers to filter the product collection by rating.',
|
||||
'woocommerce'
|
||||
),
|
||||
attributes: {
|
||||
filterType: 'rating-filter',
|
||||
heading: __( 'Filter by Rating', 'woocommerce' ),
|
||||
},
|
||||
icon: {
|
||||
src: (
|
||||
|
@ -149,7 +136,5 @@ if ( isExperimentalBuild() ) {
|
|||
},
|
||||
},
|
||||
],
|
||||
edit,
|
||||
save,
|
||||
} );
|
||||
}
|
|
@ -1,16 +1,17 @@
|
|||
{
|
||||
"$schema": "https://schemas.wp.org/trunk/block.json",
|
||||
"name": "woocommerce/product-filters-active",
|
||||
"name": "woocommerce/product-filter-active",
|
||||
"version": "1.0.0",
|
||||
"title": "Product Filters: Active Filters",
|
||||
"title": "Product Filter: Active Filters",
|
||||
"description": "Display the currently active filters.",
|
||||
"category": "woocommerce",
|
||||
"keywords": [ "WooCommerce" ],
|
||||
"textdomain": "woocommerce",
|
||||
"apiVersion": 2,
|
||||
"ancestor": [ "woocommerce/product-filters" ],
|
||||
"ancestor": [ "woocommerce/product-filter" ],
|
||||
"supports": {
|
||||
"interactivity": true,
|
||||
"inserter": false,
|
||||
"color": {
|
||||
"text": true,
|
||||
"background": false
|
|
@ -1,11 +1,10 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
|
||||
import { useBlockProps } from '@wordpress/block-editor';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import classNames from 'classnames';
|
||||
import { Disabled } from '@wordpress/components';
|
||||
import { Template } from '@wordpress/blocks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -21,20 +20,9 @@ const Edit = ( props: EditProps ) => {
|
|||
className: 'wc-block-active-filters',
|
||||
} );
|
||||
|
||||
const template: Template[] = [
|
||||
[
|
||||
'core/heading',
|
||||
{ content: __( 'Active Filters', 'woocommerce' ), level: 3 },
|
||||
],
|
||||
];
|
||||
|
||||
return (
|
||||
<div { ...blockProps }>
|
||||
<Inspector { ...props } />
|
||||
<InnerBlocks
|
||||
template={ template }
|
||||
allowedBlocks={ [ 'core/heading' ] }
|
||||
/>
|
||||
<Disabled>
|
||||
<ul
|
||||
className={ classNames( 'wc-block-active-filters__list', {
|
|
@ -13,7 +13,7 @@ type ActiveFiltersContext = {
|
|||
params: string[];
|
||||
};
|
||||
|
||||
store( 'woocommerce/product-filters-active', {
|
||||
store( 'woocommerce/product-filter-active', {
|
||||
actions: {
|
||||
clearAll: () => {
|
||||
const { params } = getContext< ActiveFiltersContext >();
|
|
@ -5,7 +5,6 @@ import { registerBlockType } from '@wordpress/blocks';
|
|||
import { Icon } from '@wordpress/icons';
|
||||
import { toggle } from '@woocommerce/icons';
|
||||
import { isExperimentalBuild } from '@woocommerce/block-settings';
|
||||
import { InnerBlocks } from '@wordpress/block-editor';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -25,6 +24,5 @@ if ( isExperimentalBuild() ) {
|
|||
),
|
||||
},
|
||||
edit: Edit,
|
||||
save: InnerBlocks.Content,
|
||||
} );
|
||||
}
|
|
@ -1,16 +1,17 @@
|
|||
{
|
||||
"$schema": "https://schemas.wp.org/trunk/block.json",
|
||||
"name": "woocommerce/product-filters-attribute",
|
||||
"name": "woocommerce/product-filter-attribute",
|
||||
"version": "1.0.0",
|
||||
"title": "Product Filters: Attribute",
|
||||
"title": "Product Filter: Attribute",
|
||||
"description": "Enable customers to filter the product grid by selecting one or more attributes, such as color.",
|
||||
"category": "woocommerce",
|
||||
"keywords": [ "WooCommerce" ],
|
||||
"textdomain": "woocommerce",
|
||||
"apiVersion": 2,
|
||||
"ancestor": [ "woocommerce/product-filters" ],
|
||||
"ancestor": [ "woocommerce/product-filter" ],
|
||||
"supports": {
|
||||
"interactivity": true,
|
||||
"inserter": false,
|
||||
"color": {
|
||||
"text": true,
|
||||
"background": false
|
|
@ -1,13 +1,9 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useEffect, useState } from '@wordpress/element';
|
||||
import {
|
||||
BlockControls,
|
||||
InnerBlocks,
|
||||
useBlockProps,
|
||||
} from '@wordpress/block-editor';
|
||||
import { BlockControls, useBlockProps } from '@wordpress/block-editor';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
import {
|
||||
useCollection,
|
||||
|
@ -25,7 +21,6 @@ import {
|
|||
withSpokenMessages,
|
||||
Notice,
|
||||
} from '@wordpress/components';
|
||||
import { Template } from '@wordpress/blocks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -88,22 +83,6 @@ const Edit = ( props: EditProps ) => {
|
|||
|
||||
const blockProps = useBlockProps();
|
||||
|
||||
const template: Template[] = [
|
||||
[
|
||||
'core/heading',
|
||||
{
|
||||
content: attributeObject
|
||||
? sprintf(
|
||||
// translators: %s is the attribute label.
|
||||
__( 'Filter by %s', 'woocommerce' ),
|
||||
attributeObject.label
|
||||
)
|
||||
: __( 'Filter Products by Attribute', 'woocommerce' ),
|
||||
level: 3,
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
useEffect( () => {
|
||||
if ( ! attributeObject?.taxonomy ) {
|
||||
return;
|
||||
|
@ -194,7 +173,7 @@ const Edit = ( props: EditProps ) => {
|
|||
</AttributesPlaceholder>
|
||||
);
|
||||
|
||||
const Wrapper = ( { children }: { children: ReactNode } ) => (
|
||||
const Wrapper = ( { children }: { children: React.ReactNode } ) => (
|
||||
<div { ...blockProps }>
|
||||
<Toolbar />
|
||||
{ children }
|
||||
|
@ -247,10 +226,6 @@ const Edit = ( props: EditProps ) => {
|
|||
return (
|
||||
<Wrapper>
|
||||
<Inspector { ...props } />
|
||||
<InnerBlocks
|
||||
template={ template }
|
||||
allowedBlocks={ [ 'core/heading' ] }
|
||||
/>
|
||||
<Disabled>
|
||||
{ displayStyle === 'dropdown' ? (
|
||||
<AttributeDropdown
|
|
@ -50,7 +50,7 @@ function getSelectedTermsFromUrl( slug: string ) {
|
|||
.filter( Boolean );
|
||||
}
|
||||
|
||||
store( 'woocommerce/product-filters-attribute', {
|
||||
store( 'woocommerce/product-filter-attribute', {
|
||||
actions: {
|
||||
navigate: () => {
|
||||
const dropdownContext = getContext< DropdownContext >(
|
|
@ -3,7 +3,6 @@
|
|||
*/
|
||||
import { registerBlockType } from '@wordpress/blocks';
|
||||
import { isExperimentalBuild } from '@woocommerce/block-settings';
|
||||
import { InnerBlocks } from '@wordpress/block-editor';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -15,6 +14,5 @@ import Edit from './edit';
|
|||
if ( isExperimentalBuild() ) {
|
||||
registerBlockType( metadata, {
|
||||
edit: Edit,
|
||||
save: InnerBlocks.Content,
|
||||
} );
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
.wp-block-woocommerce-product-filters-attribute {
|
||||
.wp-block-woocommerce-product-filter-attribute {
|
||||
.style-dropdown {
|
||||
position: relative;
|
||||
|
|
@ -1,16 +1,17 @@
|
|||
{
|
||||
"$schema": "https://schemas.wp.org/trunk/block.json",
|
||||
"name": "woocommerce/product-filters-price",
|
||||
"name": "woocommerce/product-filter-price",
|
||||
"version": "1.0.0",
|
||||
"title": "Product Filters: Price",
|
||||
"title": "Product Filter: Price",
|
||||
"description": "Enable customers to filter the product collection by choosing a price range.",
|
||||
"category": "woocommerce",
|
||||
"keywords": [ "WooCommerce" ],
|
||||
"textdomain": "woocommerce",
|
||||
"apiVersion": 2,
|
||||
"ancestor": [ "woocommerce/product-filters" ],
|
||||
"ancestor": [ "woocommerce/product-filter" ],
|
||||
"supports": {
|
||||
"interactivity": true
|
||||
"interactivity": true,
|
||||
"inserter": false
|
||||
},
|
||||
"usesContext": [ "collectionData" ],
|
||||
"attributes": {
|
|
@ -1,10 +1,8 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
|
||||
import { useBlockProps } from '@wordpress/block-editor';
|
||||
import classNames from 'classnames';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Template } from '@wordpress/blocks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -22,20 +20,9 @@ const Edit = ( props: EditProps ) => {
|
|||
} ),
|
||||
} );
|
||||
|
||||
const template: Template[] = [
|
||||
[
|
||||
'core/heading',
|
||||
{ content: __( 'Filter by Price', 'woocommerce' ), level: 3 },
|
||||
],
|
||||
];
|
||||
|
||||
return (
|
||||
<div { ...blockProps }>
|
||||
<Inspector { ...props } />
|
||||
<InnerBlocks
|
||||
template={ template }
|
||||
allowedBlocks={ [ 'core/heading' ] }
|
||||
/>
|
||||
<PriceSlider { ...props } />
|
||||
</div>
|
||||
);
|
|
@ -35,7 +35,7 @@ const getUrl = ( context: PriceFilterContext ) => {
|
|||
return url.href;
|
||||
};
|
||||
|
||||
store< PriceFilterStore >( 'woocommerce/product-filters-price', {
|
||||
store< PriceFilterStore >( 'woocommerce/product-filter-price', {
|
||||
state: {
|
||||
rangeStyle: () => {
|
||||
const { minPrice, maxPrice, minRange, maxRange } =
|
|
@ -4,7 +4,6 @@
|
|||
import { registerBlockType } from '@wordpress/blocks';
|
||||
import { Icon, currencyDollar } from '@wordpress/icons';
|
||||
import { isExperimentalBuild } from '@woocommerce/block-settings';
|
||||
import { InnerBlocks } from '@wordpress/block-editor';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -24,6 +23,5 @@ if ( isExperimentalBuild() ) {
|
|||
),
|
||||
},
|
||||
edit: Edit,
|
||||
save: InnerBlocks.Content,
|
||||
} );
|
||||
}
|
|
@ -26,7 +26,6 @@
|
|||
border-color: $white;
|
||||
}
|
||||
|
||||
|
||||
@mixin track {
|
||||
cursor: default;
|
||||
height: 1px;
|
||||
|
@ -51,15 +50,19 @@
|
|||
appearance: none;
|
||||
}
|
||||
|
||||
.wp-block-woocommerce-product-filters-price {
|
||||
.wp-block-woocommerce-product-filter-price {
|
||||
.range {
|
||||
--low: 0%;
|
||||
--high: 100%;
|
||||
--range-color: currentColor;
|
||||
--track-background: linear-gradient(to right, transparent var(--low), var(--range-color) 0, var(--range-color) var(--high), transparent 0) no-repeat 0 100% / 100% 100%;
|
||||
--track-background:
|
||||
linear-gradient(to right, transparent var(--low), var(--range-color) 0, var(--range-color) var(--high), transparent 0)
|
||||
no-repeat 0 100% / 100% 100%;
|
||||
|
||||
.rtl & {
|
||||
--track-background: linear-gradient(to left, transparent var(--low), var(--range-color) 0, var(--range-color) var(--high), transparent 0) no-repeat 0 100% / 100% 100%;
|
||||
--track-background:
|
||||
linear-gradient(to left, transparent var(--low), var(--range-color) 0, var(--range-color) var(--high), transparent 0)
|
||||
no-repeat 0 100% / 100% 100%;
|
||||
}
|
||||
|
||||
@include reset;
|
|
@ -1,18 +1,19 @@
|
|||
{
|
||||
"name": "woocommerce/product-filters-rating",
|
||||
"name": "woocommerce/product-filter-rating",
|
||||
"version": "1.0.0",
|
||||
"title": "Product Filters: Rating",
|
||||
"title": "Product Filter: Rating",
|
||||
"description": "Enable customers to filter the product collection by rating.",
|
||||
"category": "woocommerce",
|
||||
"keywords": [ "WooCommerce" ],
|
||||
"supports": {
|
||||
"interactivity": true,
|
||||
"inserter": false,
|
||||
"color": {
|
||||
"background": false,
|
||||
"text": true
|
||||
}
|
||||
},
|
||||
"ancestor": [ "woocommerce/product-filters" ],
|
||||
"ancestor": [ "woocommerce/product-filter" ],
|
||||
"usesContext": [ "collectionData" ],
|
||||
"attributes": {
|
||||
"className": {
|
|
@ -3,8 +3,8 @@
|
|||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import classnames from 'classnames';
|
||||
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
|
||||
import type { BlockEditProps, Template } from '@wordpress/blocks';
|
||||
import { useBlockProps } from '@wordpress/block-editor';
|
||||
import type { BlockEditProps } from '@wordpress/blocks';
|
||||
import Rating from '@woocommerce/base-components/product-rating';
|
||||
import {
|
||||
useQueryStateByKey,
|
||||
|
@ -48,13 +48,6 @@ const Edit = ( props: BlockEditProps< Attributes > ) => {
|
|||
className: classnames( 'wc-block-rating-filter', className ),
|
||||
} );
|
||||
|
||||
const template: Template[] = [
|
||||
[
|
||||
'core/heading',
|
||||
{ content: __( 'Filter by Rating', 'woocommerce' ), level: 3 },
|
||||
],
|
||||
];
|
||||
|
||||
const isEditor = true;
|
||||
|
||||
const setWrapperVisibility = useSetWraperVisibility();
|
||||
|
@ -170,10 +163,6 @@ const Edit = ( props: BlockEditProps< Attributes > ) => {
|
|||
<>
|
||||
<Inspector { ...props } />
|
||||
<div { ...blockProps }>
|
||||
<InnerBlocks
|
||||
template={ template }
|
||||
allowedBlocks={ [ 'core/heading' ] }
|
||||
/>
|
||||
<Disabled>
|
||||
{ displayNoProductRatingsNotice && <NoRatings /> }
|
||||
<div
|
|
@ -25,7 +25,7 @@ function getUrl( filters: Array< string | null > ) {
|
|||
return url.href;
|
||||
}
|
||||
|
||||
store( 'woocommerce/product-filters-rating', {
|
||||
store( 'woocommerce/product-filter-rating', {
|
||||
actions: {
|
||||
onCheckboxChange: () => {
|
||||
const checkboxContext = getContext< CheckboxListContext >(
|
|
@ -3,7 +3,6 @@
|
|||
*/
|
||||
import { registerBlockType } from '@wordpress/blocks';
|
||||
import { Icon, starEmpty } from '@wordpress/icons';
|
||||
import { InnerBlocks } from '@wordpress/block-editor';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -24,5 +23,4 @@ registerBlockType( metadata, {
|
|||
...metadata.attributes,
|
||||
},
|
||||
edit,
|
||||
save: InnerBlocks.Content,
|
||||
} );
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "woocommerce/product-filters-stock-status",
|
||||
"name": "woocommerce/product-filter-stock-status",
|
||||
"version": "1.0.0",
|
||||
"title": "Product Filters: Stock Status",
|
||||
"title": "Product Filter: Stock Status",
|
||||
"description": "Enable customers to filter the product collection by stock status.",
|
||||
"category": "woocommerce",
|
||||
"keywords": [ "WooCommerce", "filter", "stock" ],
|
||||
|
@ -9,6 +9,7 @@
|
|||
"interactivity": true,
|
||||
"html": false,
|
||||
"multiple": false,
|
||||
"inserter": false,
|
||||
"color": {
|
||||
"text": true,
|
||||
"background": false
|
|
@ -3,12 +3,12 @@
|
|||
*/
|
||||
import { useMemo } from '@wordpress/element';
|
||||
import classnames from 'classnames';
|
||||
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
|
||||
import { useBlockProps } from '@wordpress/block-editor';
|
||||
import { Disabled } from '@wordpress/components';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { CheckboxList } from '@woocommerce/blocks-components';
|
||||
import Label from '@woocommerce/base-components/filter-element-label';
|
||||
import type { BlockEditProps, Template } from '@wordpress/blocks';
|
||||
import type { BlockEditProps } from '@wordpress/blocks';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
import { useCollectionData } from '@woocommerce/base-context/hooks';
|
||||
|
||||
|
@ -36,16 +36,6 @@ const Edit = ( props: BlockEditProps< BlockProps > ) => {
|
|||
),
|
||||
} );
|
||||
|
||||
const template: Template[] = [
|
||||
[
|
||||
'core/heading',
|
||||
{
|
||||
content: __( 'Filter by Stock Status', 'woocommerce' ),
|
||||
level: 3,
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
const { showCounts, displayStyle } = props.attributes;
|
||||
const stockStatusOptions: Record< string, string > = getSetting(
|
||||
'stockStatusOptions',
|
||||
|
@ -88,10 +78,6 @@ const Edit = ( props: BlockEditProps< BlockProps > ) => {
|
|||
{
|
||||
<div { ...blockProps }>
|
||||
<Inspector { ...props } />
|
||||
<InnerBlocks
|
||||
template={ template }
|
||||
allowedBlocks={ [ 'core/heading' ] }
|
||||
/>
|
||||
<Disabled>
|
||||
<div
|
||||
className={ classnames(
|
|
@ -24,7 +24,7 @@ const getUrl = ( activeFilters: string ) => {
|
|||
return url.href;
|
||||
};
|
||||
|
||||
store( 'woocommerce/product-filters-stock-status', {
|
||||
store( 'woocommerce/product-filter-stock-status', {
|
||||
actions: {
|
||||
onCheckboxChange: () => {
|
||||
const checkboxContext = getContext< CheckboxListContext >(
|
|
@ -4,7 +4,6 @@
|
|||
import { registerBlockType } from '@wordpress/blocks';
|
||||
import { Icon, box } from '@wordpress/icons';
|
||||
import { isExperimentalBuild } from '@woocommerce/block-settings';
|
||||
import { InnerBlocks } from '@wordpress/block-editor';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
|
@ -24,6 +23,5 @@ if ( isExperimentalBuild() ) {
|
|||
),
|
||||
},
|
||||
edit,
|
||||
save: InnerBlocks.Content,
|
||||
} );
|
||||
}
|
|
@ -9,7 +9,7 @@ export type FilterType =
|
|||
| 'rating-filter'
|
||||
| 'active-filters'
|
||||
| 'stock-filter'
|
||||
| 'product-filters';
|
||||
| 'product-filter';
|
||||
|
||||
export type BlockAttributes = {
|
||||
filterType: FilterType;
|
|
@ -1,82 +0,0 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
|
||||
import { Template } from '@wordpress/blocks';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { getSetting } from '@woocommerce/settings';
|
||||
import type { AttributeSetting } from '@woocommerce/types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { EditProps, FilterType } from './types';
|
||||
import { getAllowedBlocks } from './utils';
|
||||
import Downgrade from './components/downgrade';
|
||||
import Warning from './components/warning';
|
||||
import './editor.scss';
|
||||
|
||||
const DISALLOWED_BLOCKS = [
|
||||
'woocommerce/filter-wrapper',
|
||||
'woocommerce/product-filters',
|
||||
];
|
||||
|
||||
const ATTRIBUTES = getSetting< AttributeSetting[] >( 'attributes', [] );
|
||||
|
||||
const firstAttribute = ATTRIBUTES.find( Boolean );
|
||||
|
||||
const templates: Partial< Record< FilterType, Template[] > > = {
|
||||
'active-filters': [ [ 'woocommerce/product-filters-active', {} ] ],
|
||||
'price-filter': [ [ 'woocommerce/product-filters-price', {} ] ],
|
||||
'stock-filter': [ [ 'woocommerce/product-filters-stock-status', {} ] ],
|
||||
'rating-filter': [ [ 'woocommerce/product-filters-rating', {} ] ],
|
||||
'product-filters': [
|
||||
[ 'woocommerce/product-filters-active', {} ],
|
||||
[ 'woocommerce/product-filters-price', {} ],
|
||||
[ 'woocommerce/product-filters-stock-status', {} ],
|
||||
[ 'woocommerce/product-filters-rating', {} ],
|
||||
],
|
||||
};
|
||||
|
||||
if ( firstAttribute ) {
|
||||
templates[ 'attribute-filter' ] = [
|
||||
[
|
||||
'woocommerce/product-filters-attribute',
|
||||
{ attributeId: parseInt( firstAttribute?.attribute_id, 10 ) },
|
||||
],
|
||||
];
|
||||
|
||||
templates[ 'product-filters' ]?.push( [
|
||||
'woocommerce/product-filters-attribute',
|
||||
{ attributeId: parseInt( firstAttribute?.attribute_id, 10 ) },
|
||||
] );
|
||||
}
|
||||
|
||||
const Edit = ( props: EditProps ) => {
|
||||
const allowedBlocks = getAllowedBlocks( DISALLOWED_BLOCKS );
|
||||
|
||||
const template = templates[ props.attributes.filterType ];
|
||||
|
||||
const blockProps = useBlockProps();
|
||||
|
||||
const isNested = useSelect( ( select ) => {
|
||||
const { getBlockParentsByBlockName } = select( 'core/block-editor' );
|
||||
return !! getBlockParentsByBlockName(
|
||||
props.clientId,
|
||||
'woocommerce/product-collection'
|
||||
).length;
|
||||
} );
|
||||
|
||||
return (
|
||||
<nav { ...blockProps }>
|
||||
{ ! isNested && <Warning /> }
|
||||
<Downgrade clientId={ props.clientId } />
|
||||
<InnerBlocks
|
||||
template={ template }
|
||||
allowedBlocks={ allowedBlocks }
|
||||
/>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Edit;
|
|
@ -88,27 +88,27 @@ const blocks = {
|
|||
},
|
||||
'single-product': {},
|
||||
'stock-filter': {},
|
||||
'product-filters': {
|
||||
'product-filter': {
|
||||
isExperimental: true,
|
||||
},
|
||||
'product-filters-stock-status': {
|
||||
'product-filter-stock-status': {
|
||||
isExperimental: true,
|
||||
customDir: 'product-filters/inner-blocks/stock-filter',
|
||||
customDir: 'product-filter/inner-blocks/stock-filter',
|
||||
},
|
||||
'product-filters-price': {
|
||||
customDir: 'product-filters/inner-blocks/price-filter',
|
||||
'product-filter-price': {
|
||||
customDir: 'product-filter/inner-blocks/price-filter',
|
||||
isExperimental: true,
|
||||
},
|
||||
'product-filters-attribute': {
|
||||
customDir: 'product-filters/inner-blocks/attribute-filter',
|
||||
'product-filter-attribute': {
|
||||
customDir: 'product-filter/inner-blocks/attribute-filter',
|
||||
isExperimental: true,
|
||||
},
|
||||
'product-filters-rating': {
|
||||
customDir: 'product-filters/inner-blocks/rating-filter',
|
||||
'product-filter-rating': {
|
||||
customDir: 'product-filter/inner-blocks/rating-filter',
|
||||
isExperimental: true,
|
||||
},
|
||||
'product-filters-active': {
|
||||
customDir: 'product-filters/inner-blocks/active-filters',
|
||||
'product-filter-active': {
|
||||
customDir: 'product-filter/inner-blocks/active-filters',
|
||||
isExperimental: true,
|
||||
},
|
||||
'order-confirmation-summary': {
|
||||
|
|
|
@ -3,39 +3,30 @@
|
|||
*/
|
||||
import { test, expect } from '@woocommerce/e2e-playwright-utils';
|
||||
|
||||
const wrapperBlock = {
|
||||
name: 'woocommerce/product-filters',
|
||||
title: 'Product Filters',
|
||||
};
|
||||
const filterBlocks = [
|
||||
{
|
||||
name: 'woocommerce/product-filters-price',
|
||||
title: 'Product Filters: Price',
|
||||
variation: 'Product Filters: Price',
|
||||
name: 'woocommerce/product-filter-price',
|
||||
title: 'Product Filter: Price',
|
||||
heading: 'Filter by Price',
|
||||
},
|
||||
{
|
||||
name: 'woocommerce/product-filters-stock-status',
|
||||
title: 'Product Filters: Stock Status',
|
||||
variation: 'Product Filters: Stock Status',
|
||||
name: 'woocommerce/product-filter-stock-status',
|
||||
title: 'Product Filter: Stock Status',
|
||||
heading: 'Filter by Stock Status',
|
||||
},
|
||||
{
|
||||
name: 'woocommerce/product-filters-rating',
|
||||
title: 'Product Filters: Rating',
|
||||
variation: 'Product Filters: Rating',
|
||||
name: 'woocommerce/product-filter-rating',
|
||||
title: 'Product Filter: Rating',
|
||||
heading: 'Filter by Rating',
|
||||
},
|
||||
{
|
||||
name: 'woocommerce/product-filters-attribute',
|
||||
title: 'Product Filters: Attribute',
|
||||
variation: 'Product Filters: Attribute',
|
||||
heading: 'Filter by ', // The attribute filter comes with a dynamic title
|
||||
name: 'woocommerce/product-filter-attribute',
|
||||
title: 'Product Filter: Attribute',
|
||||
heading: 'Filter by Attribute',
|
||||
},
|
||||
{
|
||||
name: 'woocommerce/product-filters-active',
|
||||
title: 'Product Filters: Active Filters',
|
||||
variation: 'Product Filters: Active Filters',
|
||||
name: 'woocommerce/product-filter-active',
|
||||
title: 'Product Filter: Active Filters',
|
||||
heading: 'Active Filters',
|
||||
},
|
||||
];
|
||||
|
@ -45,25 +36,13 @@ test.describe( 'Filter blocks registration', async () => {
|
|||
await admin.createNewPost();
|
||||
} );
|
||||
|
||||
test( 'Wrapper block can be inserted through the inserter', async ( {
|
||||
test( 'Variations can be inserted through the inserter.', async ( {
|
||||
editor,
|
||||
editorUtils,
|
||||
} ) => {
|
||||
await editorUtils.insertBlockUsingGlobalInserter( wrapperBlock.title );
|
||||
|
||||
await expect(
|
||||
editor.canvas.getByLabel( `Block: ${ wrapperBlock.title }`, {
|
||||
exact: true,
|
||||
} )
|
||||
).toBeVisible();
|
||||
} );
|
||||
|
||||
test( 'Wrapper block contains all filter blocks by default', async ( {
|
||||
editor,
|
||||
editorUtils,
|
||||
} ) => {
|
||||
await editorUtils.insertBlockUsingGlobalInserter( wrapperBlock.title );
|
||||
for ( const block of filterBlocks ) {
|
||||
await editorUtils.insertBlockUsingGlobalInserter( block.title );
|
||||
|
||||
await expect(
|
||||
editor.canvas.getByLabel( `Block: ${ block.title }` )
|
||||
).toBeVisible();
|
||||
|
@ -74,27 +53,15 @@ test.describe( 'Filter blocks registration', async () => {
|
|||
editor,
|
||||
editorUtils,
|
||||
} ) => {
|
||||
await editorUtils.insertBlockUsingGlobalInserter( wrapperBlock.title );
|
||||
for ( const block of filterBlocks ) {
|
||||
await editorUtils.insertBlockUsingGlobalInserter( block.title );
|
||||
|
||||
await expect(
|
||||
editor.canvas
|
||||
.getByLabel( `Block: ${ block.title }` )
|
||||
.getByLabel( `Block: Product Filter` )
|
||||
.getByLabel( 'Block: Heading' )
|
||||
.and( editor.canvas.getByText( block.heading ) )
|
||||
).toBeVisible();
|
||||
}
|
||||
} );
|
||||
|
||||
test( 'Variations can be inserted through the inserter.', async ( {
|
||||
editor,
|
||||
editorUtils,
|
||||
} ) => {
|
||||
for ( const block of filterBlocks ) {
|
||||
await editorUtils.insertBlockUsingGlobalInserter( block.variation );
|
||||
|
||||
await expect(
|
||||
editor.canvas.getByLabel( `Block: ${ block.title }` )
|
||||
).toBeVisible();
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: add
|
||||
|
||||
[Experimental] Reintroduce a wrapper block for the interactivity powered filter blocks.
|
|
@ -2,7 +2,7 @@
|
|||
namespace Automattic\WooCommerce\Blocks\BlockTypes;
|
||||
|
||||
/**
|
||||
* FilledCartBlock class.
|
||||
* FilterWrapper class.
|
||||
*/
|
||||
class FilterWrapper extends AbstractBlock {
|
||||
/**
|
||||
|
|
|
@ -5,15 +5,15 @@ use Automattic\WooCommerce\Blocks\QueryFilters;
|
|||
use Automattic\WooCommerce\Blocks\Package;
|
||||
|
||||
/**
|
||||
* Product Filters Block.
|
||||
* Product Filter Block.
|
||||
*/
|
||||
final class ProductFilters extends AbstractBlock {
|
||||
final class ProductFilter extends AbstractBlock {
|
||||
/**
|
||||
* Block name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $block_name = 'product-filters';
|
||||
protected $block_name = 'product-filter';
|
||||
|
||||
/**
|
||||
* Cache the current response from the API.
|
||||
|
@ -70,6 +70,55 @@ final class ProductFilters extends AbstractBlock {
|
|||
$this->asset_data_registry->add( 'isWidgetEditor', 'widgets.php' === $pagenow || 'customize.php' === $pagenow, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the collection data is empty.
|
||||
*
|
||||
* @param mixed $attributes - Block attributes.
|
||||
* @return bool - Whether the collection data is empty.
|
||||
*/
|
||||
private function collection_data_is_empty( $attributes ) {
|
||||
$filter_type = $attributes['filterType'];
|
||||
|
||||
if ( 'active-filters' !== $filter_type && empty( $this->current_response ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( 'attribute-filter' === $filter_type ) {
|
||||
return empty( $this->current_response['attribute_counts'] );
|
||||
}
|
||||
|
||||
if ( 'rating-filter' === $filter_type ) {
|
||||
return empty( $this->current_response['rating_counts'] );
|
||||
}
|
||||
|
||||
if ( 'price-filter' === $filter_type ) {
|
||||
return empty( $this->current_response['price_range'] ) || ( $this->current_response['price_range']['min_price'] === $this->current_response['price_range']['max_price'] );
|
||||
}
|
||||
|
||||
if ( 'stock-filter' === $filter_type ) {
|
||||
return empty( $this->current_response['stock_status_counts'] );
|
||||
}
|
||||
|
||||
if ( 'active-filters' === $filter_type ) {
|
||||
// Duplicate query param logic from ProductFilterActive block, to determine if we should
|
||||
// display the ProductFilter block or not.
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '';
|
||||
$parsed_url = wp_parse_url( esc_url_raw( $request_uri ) );
|
||||
|
||||
$url_query_params = [];
|
||||
|
||||
if ( isset( $parsed_url['query'] ) ) {
|
||||
parse_str( $parsed_url['query'], $url_query_params );
|
||||
}
|
||||
|
||||
// phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment
|
||||
return empty( array_unique( apply_filters( 'collection_filter_query_param_keys', array(), array_keys( $url_query_params ) ) ) );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the block.
|
||||
*
|
||||
|
@ -83,22 +132,82 @@ final class ProductFilters extends AbstractBlock {
|
|||
return $content;
|
||||
}
|
||||
|
||||
if ( $this->collection_data_is_empty( $attributes ) ) {
|
||||
return $this->render_empty_block( $block );
|
||||
}
|
||||
|
||||
return $this->render_filter_block( $content, $block );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the current response, must be done before rendering.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function reset_current_response() {
|
||||
/**
|
||||
* At this point, WP starts rendering the Collection Filters block,
|
||||
* When WP starts rendering the Product Filters block,
|
||||
* we can safely unset the current response.
|
||||
*/
|
||||
$this->current_response = null;
|
||||
}
|
||||
|
||||
$attributes_data = array(
|
||||
/**
|
||||
* Render the block when it's empty.
|
||||
*
|
||||
* @param mixed $block - Block instance.
|
||||
* @return string - Rendered block type output.
|
||||
*/
|
||||
private function render_empty_block( $block ) {
|
||||
$this->reset_current_response();
|
||||
|
||||
$attributes = array(
|
||||
'data-wc-interactive' => wp_json_encode( array( 'namespace' => $this->get_full_block_name() ) ),
|
||||
'class' => 'wc-block-collection-filters',
|
||||
'class' => 'wc-block-product-filters',
|
||||
);
|
||||
|
||||
if ( ! isset( $block->context['queryId'] ) ) {
|
||||
$attributes_data['data-wc-navigation-id'] = sprintf(
|
||||
'wc-collection-filters-%s',
|
||||
md5( wp_json_encode( $block->parsed_block['innerBlocks'] ) )
|
||||
);
|
||||
$attributes['data-wc-navigation-id'] = $this->generate_navigation_id( $block );
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'<nav %1$s></nav>',
|
||||
get_block_wrapper_attributes(
|
||||
$attributes
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique navigation ID for the block.
|
||||
*
|
||||
* @param mixed $block - Block instance.
|
||||
* @return string - Unique navigation ID.
|
||||
*/
|
||||
private function generate_navigation_id( $block ) {
|
||||
return sprintf(
|
||||
'wc-product-filter-%s',
|
||||
md5( wp_json_encode( $block->parsed_block['innerBlocks'] ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the block when it's not empty.
|
||||
*
|
||||
* @param string $content - Block content.
|
||||
* @param WP_Block $block - Block instance.
|
||||
* @return string - Rendered block type output.
|
||||
*/
|
||||
private function render_filter_block( $content, $block ) {
|
||||
$this->reset_current_response();
|
||||
|
||||
$attributes_data = array(
|
||||
'data-wc-interactive' => wp_json_encode( array( 'namespace' => $this->get_full_block_name() ) ),
|
||||
'class' => 'wc-block-product-filters',
|
||||
);
|
||||
|
||||
if ( ! isset( $block->context['queryId'] ) ) {
|
||||
$attributes_data['data-wc-navigation-id'] = $this->generate_navigation_id( $block );
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
|
@ -122,7 +231,7 @@ final class ProductFilters extends AbstractBlock {
|
|||
}
|
||||
|
||||
/**
|
||||
* When the first direct child of Collection Filters is rendering, we
|
||||
* When the first direct child of Product Filters is rendering, we
|
||||
* hydrate and cache the collection data response.
|
||||
*/
|
||||
if (
|
|
@ -2,15 +2,15 @@
|
|||
namespace Automattic\WooCommerce\Blocks\BlockTypes;
|
||||
|
||||
/**
|
||||
* Product Filters: Active Block.
|
||||
* Product Filter: Active Block.
|
||||
*/
|
||||
final class ProductFiltersActive extends AbstractBlock {
|
||||
final class ProductFilterActive extends AbstractBlock {
|
||||
/**
|
||||
* Block name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $block_name = 'product-filters-active';
|
||||
protected $block_name = 'product-filter-active';
|
||||
|
||||
/**
|
||||
* Render the block.
|
||||
|
@ -66,7 +66,6 @@ final class ProductFiltersActive extends AbstractBlock {
|
|||
|
||||
<div <?php echo $wrapper_attributes; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
|
||||
<?php if ( ! empty( $active_filters ) ) : ?>
|
||||
<?php echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<ul class="wc-block-active-filters__list %3$s">
|
||||
<?php foreach ( $active_filters as $filter ) : ?>
|
||||
<li>
|
|
@ -5,16 +5,16 @@ use Automattic\WooCommerce\Blocks\InteractivityComponents\Dropdown;
|
|||
use Automattic\WooCommerce\Blocks\InteractivityComponents\CheckboxList;
|
||||
|
||||
/**
|
||||
* Product Filters: Attribute Block.
|
||||
* Product Filter: Attribute Block.
|
||||
*/
|
||||
final class ProductFiltersAttribute extends AbstractBlock {
|
||||
final class ProductFilterAttribute extends AbstractBlock {
|
||||
|
||||
/**
|
||||
* Block name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $block_name = 'product-filters-attribute';
|
||||
protected $block_name = 'product-filter-attribute';
|
||||
|
||||
/**
|
||||
* Initialize this block type.
|
||||
|
@ -154,7 +154,6 @@ final class ProductFiltersAttribute extends AbstractBlock {
|
|||
)
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
$attribute_terms = get_terms(
|
|
@ -2,16 +2,16 @@
|
|||
namespace Automattic\WooCommerce\Blocks\BlockTypes;
|
||||
|
||||
/**
|
||||
* Product Filters: Price Block.
|
||||
* Product Filter: Price Block.
|
||||
*/
|
||||
final class ProductFiltersPrice extends AbstractBlock {
|
||||
final class ProductFilterPrice extends AbstractBlock {
|
||||
|
||||
/**
|
||||
* Block name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $block_name = 'product-filters-price';
|
||||
protected $block_name = 'product-filter-price';
|
||||
|
||||
const MIN_PRICE_QUERY_VAR = 'min_price';
|
||||
const MAX_PRICE_QUERY_VAR = 'max_price';
|
|
@ -5,17 +5,17 @@ use Automattic\WooCommerce\Blocks\InteractivityComponents\CheckboxList;
|
|||
use Automattic\WooCommerce\Blocks\InteractivityComponents\Dropdown;
|
||||
|
||||
/**
|
||||
* Product Filters: Rating Block
|
||||
* Product Filter: Rating Block
|
||||
*
|
||||
* @package Automattic\WooCommerce\Blocks\BlockTypes
|
||||
*/
|
||||
final class ProductFiltersRating extends AbstractBlock {
|
||||
final class ProductFilterRating extends AbstractBlock {
|
||||
/**
|
||||
* Block name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $block_name = 'product-filters-rating';
|
||||
protected $block_name = 'product-filter-rating';
|
||||
|
||||
const RATING_FILTER_QUERY_VAR = 'rating_filter';
|
||||
|
|
@ -5,16 +5,16 @@ use Automattic\WooCommerce\Blocks\InteractivityComponents\Dropdown;
|
|||
use Automattic\WooCommerce\Blocks\InteractivityComponents\CheckboxList;
|
||||
|
||||
/**
|
||||
* Product Filters: Stock Status Block.
|
||||
* Product Filter: Stock Status Block.
|
||||
*/
|
||||
final class ProductFiltersStockStatus extends AbstractBlock {
|
||||
final class ProductFilterStockStatus extends AbstractBlock {
|
||||
|
||||
/**
|
||||
* Block name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $block_name = 'product-filters-stock-status';
|
||||
protected $block_name = 'product-filter-stock-status';
|
||||
|
||||
const STOCK_STATUS_QUERY_VAR = 'filter_stock_status';
|
||||
|
|
@ -298,12 +298,12 @@ final class BlockTypesController {
|
|||
);
|
||||
|
||||
if ( Package::feature()->is_experimental_build() ) {
|
||||
$block_types[] = 'ProductFilters';
|
||||
$block_types[] = 'ProductFiltersStockStatus';
|
||||
$block_types[] = 'ProductFiltersPrice';
|
||||
$block_types[] = 'ProductFiltersAttribute';
|
||||
$block_types[] = 'ProductFiltersRating';
|
||||
$block_types[] = 'ProductFiltersActive';
|
||||
$block_types[] = 'ProductFilter';
|
||||
$block_types[] = 'ProductFilterStockStatus';
|
||||
$block_types[] = 'ProductFilterPrice';
|
||||
$block_types[] = 'ProductFilterAttribute';
|
||||
$block_types[] = 'ProductFilterRating';
|
||||
$block_types[] = 'ProductFilterActive';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue