[Experimental] Product filters/remove template parts (#52041)
* Remove product filters template part * Remove product filters overlay template part * Update e2e tests * Add changefile(s) from automation for the following project(s): woocommerce-blocks, woocommerce * Fix linting * Remove unused template part class and remove overlay navigation --------- Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
parent
92c8f4168d
commit
bd838d824a
|
@ -21,8 +21,8 @@
|
||||||
"background": true,
|
"background": true,
|
||||||
"text": true
|
"text": true
|
||||||
},
|
},
|
||||||
"multiple": false,
|
"multiple": true,
|
||||||
"inserter": false,
|
"inserter": true,
|
||||||
"interactivity": true,
|
"interactivity": true,
|
||||||
"typography": {
|
"typography": {
|
||||||
"fontSize": true,
|
"fontSize": true,
|
||||||
|
@ -46,15 +46,6 @@
|
||||||
},
|
},
|
||||||
"textdomain": "woocommerce",
|
"textdomain": "woocommerce",
|
||||||
"usesContext": [ "postId" ],
|
"usesContext": [ "postId" ],
|
||||||
"providesContext": {
|
|
||||||
"woocommerce/product-filters/overlay": "overlay"
|
|
||||||
},
|
|
||||||
"attributes": {
|
|
||||||
"overlay": {
|
|
||||||
"type": "string",
|
|
||||||
"default": "never"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"viewScript": "wc-product-filters-frontend",
|
"viewScript": "wc-product-filters-frontend",
|
||||||
"example": {}
|
"example": {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
export const BlockOverlayAttribute = {
|
|
||||||
NEVER: 'never',
|
|
||||||
MOBILE: 'mobile',
|
|
||||||
ALWAYS: 'always',
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const EXCLUDED_BLOCKS = [
|
export const EXCLUDED_BLOCKS = [
|
||||||
'woocommerce/product-filters',
|
'woocommerce/product-filters',
|
||||||
'woocommerce/product-filter-attribute',
|
'woocommerce/product-filter-attribute',
|
||||||
|
|
|
@ -1,40 +1,15 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { getSetting } from '@woocommerce/settings';
|
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
|
||||||
import {
|
import { BlockEditProps, InnerBlockTemplate } from '@wordpress/blocks';
|
||||||
InnerBlocks,
|
|
||||||
InspectorControls,
|
|
||||||
useBlockProps,
|
|
||||||
useInnerBlocksProps,
|
|
||||||
} from '@wordpress/block-editor';
|
|
||||||
import {
|
|
||||||
BlockEditProps,
|
|
||||||
BlockInstance,
|
|
||||||
InnerBlockTemplate,
|
|
||||||
createBlock,
|
|
||||||
} from '@wordpress/blocks';
|
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { useEffect } from '@wordpress/element';
|
|
||||||
import { select, dispatch } from '@wordpress/data';
|
|
||||||
import { useLocalStorageState } from '@woocommerce/base-hooks';
|
|
||||||
import {
|
|
||||||
ExternalLink,
|
|
||||||
PanelBody,
|
|
||||||
// @ts-expect-error - no types.
|
|
||||||
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
|
|
||||||
__experimentalToggleGroupControl as ToggleGroupControl,
|
|
||||||
// @ts-expect-error - no types.
|
|
||||||
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
|
|
||||||
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
|
|
||||||
} from '@wordpress/components';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import './editor.scss';
|
import './editor.scss';
|
||||||
import { type BlockAttributes } from './types';
|
import { type BlockAttributes } from './types';
|
||||||
import { BlockOverlayAttribute } from './constants';
|
|
||||||
|
|
||||||
const TEMPLATE: InnerBlockTemplate[] = [
|
const TEMPLATE: InnerBlockTemplate[] = [
|
||||||
[
|
[
|
||||||
|
@ -73,138 +48,12 @@ const TEMPLATE: InnerBlockTemplate[] = [
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
export const Edit = ( {
|
export const Edit = ( {}: BlockEditProps< BlockAttributes > ) => {
|
||||||
setAttributes,
|
|
||||||
attributes,
|
|
||||||
clientId,
|
|
||||||
}: BlockEditProps< BlockAttributes > ) => {
|
|
||||||
const blockProps = useBlockProps();
|
const blockProps = useBlockProps();
|
||||||
|
|
||||||
const templatePartEditUri = getSetting< string >(
|
|
||||||
'templatePartProductFiltersOverlayEditUri',
|
|
||||||
''
|
|
||||||
);
|
|
||||||
|
|
||||||
const [
|
|
||||||
productFiltersOverlayNavigationAttributes,
|
|
||||||
setProductFiltersOverlayNavigationAttributes,
|
|
||||||
] = useLocalStorageState< Record< string, unknown > >(
|
|
||||||
'product-filters-overlay-navigation-attributes',
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect( () => {
|
|
||||||
const filtersClientIds = select( 'core/block-editor' ).getBlocksByName(
|
|
||||||
'woocommerce/product-filters'
|
|
||||||
);
|
|
||||||
|
|
||||||
let overlayBlock:
|
|
||||||
| BlockInstance< { [ k: string ]: unknown } >
|
|
||||||
| undefined;
|
|
||||||
|
|
||||||
for ( const filterClientId of filtersClientIds ) {
|
|
||||||
const filterBlock =
|
|
||||||
select( 'core/block-editor' ).getBlock( filterClientId );
|
|
||||||
|
|
||||||
if ( filterBlock ) {
|
|
||||||
for ( const innerBlock of filterBlock.innerBlocks ) {
|
|
||||||
if (
|
|
||||||
innerBlock.name ===
|
|
||||||
'woocommerce/product-filters-overlay-navigation' &&
|
|
||||||
innerBlock.attributes.triggerType === 'open-overlay'
|
|
||||||
) {
|
|
||||||
overlayBlock = innerBlock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( attributes.overlay === 'never' && overlayBlock ) {
|
|
||||||
setProductFiltersOverlayNavigationAttributes(
|
|
||||||
overlayBlock.attributes
|
|
||||||
);
|
|
||||||
|
|
||||||
dispatch( 'core/block-editor' ).updateBlockAttributes(
|
|
||||||
overlayBlock.clientId,
|
|
||||||
{
|
|
||||||
lock: {},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
dispatch( 'core/block-editor' ).removeBlock(
|
|
||||||
overlayBlock.clientId
|
|
||||||
);
|
|
||||||
} else if ( attributes.overlay !== 'never' && ! overlayBlock ) {
|
|
||||||
if ( productFiltersOverlayNavigationAttributes ) {
|
|
||||||
productFiltersOverlayNavigationAttributes.triggerType =
|
|
||||||
'open-overlay';
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch( 'core/block-editor' ).insertBlock(
|
|
||||||
createBlock(
|
|
||||||
'woocommerce/product-filters-overlay-navigation',
|
|
||||||
productFiltersOverlayNavigationAttributes
|
|
||||||
? productFiltersOverlayNavigationAttributes
|
|
||||||
: {
|
|
||||||
align: 'left',
|
|
||||||
triggerType: 'open-overlay',
|
|
||||||
lock: { move: true, remove: true },
|
|
||||||
}
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
clientId,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [
|
|
||||||
attributes.overlay,
|
|
||||||
clientId,
|
|
||||||
productFiltersOverlayNavigationAttributes,
|
|
||||||
setProductFiltersOverlayNavigationAttributes,
|
|
||||||
] );
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div { ...blockProps }>
|
<div { ...blockProps }>
|
||||||
<InspectorControls>
|
|
||||||
<PanelBody title={ __( 'Overlay', 'woocommerce' ) }>
|
|
||||||
<ToggleGroupControl
|
|
||||||
className="wc-block-editor-product-filters__overlay-toggle"
|
|
||||||
isBlock={ true }
|
|
||||||
value={ attributes.overlay }
|
|
||||||
onChange={ ( value: BlockAttributes[ 'overlay' ] ) => {
|
|
||||||
setAttributes( { overlay: value } );
|
|
||||||
} }
|
|
||||||
>
|
|
||||||
<ToggleGroupControlOption
|
|
||||||
value={ BlockOverlayAttribute.NEVER }
|
|
||||||
label={ __( 'Never', 'woocommerce' ) }
|
|
||||||
/>
|
|
||||||
<ToggleGroupControlOption
|
|
||||||
value={ BlockOverlayAttribute.MOBILE }
|
|
||||||
label={ __( 'Mobile', 'woocommerce' ) }
|
|
||||||
/>
|
|
||||||
<ToggleGroupControlOption
|
|
||||||
value={ BlockOverlayAttribute.ALWAYS }
|
|
||||||
label={ __( 'Always', 'woocommerce' ) }
|
|
||||||
/>
|
|
||||||
</ToggleGroupControl>
|
|
||||||
{ attributes.overlay !== 'never' && (
|
|
||||||
<ExternalLink
|
|
||||||
href={ templatePartEditUri }
|
|
||||||
className="wc-block-editor-product-filters__overlay-link"
|
|
||||||
>
|
|
||||||
{ __( 'Edit overlay', 'woocommerce' ) }
|
|
||||||
</ExternalLink>
|
|
||||||
) }
|
|
||||||
</PanelBody>
|
|
||||||
</InspectorControls>
|
|
||||||
<InnerBlocks templateLock={ false } template={ TEMPLATE } />
|
<InnerBlocks templateLock={ false } template={ TEMPLATE } />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Save = () => {
|
|
||||||
const blockProps = useBlockProps.save();
|
|
||||||
const innerBlocksProps = useInnerBlocksProps.save( blockProps );
|
|
||||||
return <div { ...innerBlocksProps } />;
|
|
||||||
};
|
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
"supports": {
|
"supports": {
|
||||||
"interactivity": true,
|
"interactivity": true,
|
||||||
"align": [ "left", "right", "center"],
|
"align": [ "left", "right", "center"],
|
||||||
"inserter": false,
|
"inserter": true,
|
||||||
"color": {
|
"color": {
|
||||||
"__experimentalDefaultControls": {
|
"__experimentalDefaultControls": {
|
||||||
"text": false,
|
"text": false,
|
||||||
|
|
|
@ -12,12 +12,7 @@ import { filter, filterThreeLines } from '@woocommerce/icons';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
import type {
|
import type { BlockAttributes, BlockVariationTriggerType } from './types';
|
||||||
BlockAttributes,
|
|
||||||
BlockContext,
|
|
||||||
BlockVariationTriggerType,
|
|
||||||
} from './types';
|
|
||||||
import { BlockOverlayAttribute as ProductFiltersBlockOverlayAttribute } from '../../constants';
|
|
||||||
import './editor.scss';
|
import './editor.scss';
|
||||||
import { Inspector } from './inspector-controls';
|
import { Inspector } from './inspector-controls';
|
||||||
|
|
||||||
|
@ -128,9 +123,9 @@ const OverlayNavigationContent = ( {
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type BlockProps = BlockEditProps< BlockAttributes > & { context: BlockContext };
|
type BlockProps = BlockEditProps< BlockAttributes >;
|
||||||
|
|
||||||
export const Edit = ( { attributes, setAttributes, context }: BlockProps ) => {
|
export const Edit = ( { attributes, setAttributes }: BlockProps ) => {
|
||||||
const {
|
const {
|
||||||
navigationStyle,
|
navigationStyle,
|
||||||
buttonStyle,
|
buttonStyle,
|
||||||
|
@ -139,57 +134,19 @@ export const Edit = ( { attributes, setAttributes, context }: BlockProps ) => {
|
||||||
style,
|
style,
|
||||||
triggerType,
|
triggerType,
|
||||||
} = attributes;
|
} = attributes;
|
||||||
const { 'woocommerce/product-filters/overlay': productFiltersOverlayMode } =
|
|
||||||
context;
|
|
||||||
const blockProps = useBlockProps( {
|
const blockProps = useBlockProps( {
|
||||||
className: clsx( 'wc-block-product-filters-overlay-navigation', {
|
className: clsx( 'wc-block-product-filters-overlay-navigation', {
|
||||||
'wp-block-button__link wp-element-button': buttonStyle !== 'link',
|
'wp-block-button__link wp-element-button': buttonStyle !== 'link',
|
||||||
} ),
|
} ),
|
||||||
} );
|
} );
|
||||||
const {
|
|
||||||
isWithinProductFiltersOverlayTemplatePart,
|
|
||||||
}: {
|
|
||||||
isWithinProductFiltersOverlayTemplatePart: boolean;
|
|
||||||
} = useSelect( ( select ) => {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
const { getCurrentPostId, getCurrentPostType } =
|
|
||||||
select( 'core/editor' );
|
|
||||||
const currentPostId = getCurrentPostId< string >();
|
|
||||||
const currentPostIdParts = currentPostId?.split( '//' );
|
|
||||||
const currentPostType = getCurrentPostType< string >();
|
|
||||||
let isProductFiltersOverlayTemplatePart = false;
|
|
||||||
|
|
||||||
if (
|
|
||||||
currentPostType === 'wp_template_part' &&
|
|
||||||
currentPostIdParts?.length > 1
|
|
||||||
) {
|
|
||||||
const [ , postId ] = currentPostIdParts;
|
|
||||||
isProductFiltersOverlayTemplatePart =
|
|
||||||
postId === 'product-filters-overlay';
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
isWithinProductFiltersOverlayTemplatePart:
|
|
||||||
isProductFiltersOverlayTemplatePart,
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
const shouldHideBlock = () => {
|
const shouldHideBlock = () => {
|
||||||
if ( triggerType === 'open-overlay' ) {
|
if ( triggerType === 'open-overlay' ) {
|
||||||
if (
|
|
||||||
productFiltersOverlayMode ===
|
|
||||||
ProductFiltersBlockOverlayAttribute.NEVER
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isWithinProductFiltersOverlayTemplatePart ) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
// We need useInnerBlocksProps because Gutenberg only applies layout classes
|
// We need useInnerBlocksProps because Gutenberg only applies layout classes
|
||||||
// to parent block. We don't have any inner blocks but we want to use the
|
// to parent block. We don't have any inner blocks but we want to use the
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { BlockOverlayAttributeOptions as ProductFiltersBlockOverlayAttributeOptions } from '../../types';
|
|
||||||
|
|
||||||
type BorderRadius = {
|
type BorderRadius = {
|
||||||
bottomLeft: string;
|
bottomLeft: string;
|
||||||
bottomRight: string;
|
bottomRight: string;
|
||||||
|
@ -14,18 +9,12 @@ type BorderSide = {
|
||||||
width: string;
|
width: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface BlockContext {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
'woocommerce/product-filters/overlay': ProductFiltersBlockOverlayAttributeOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type BlockVariationTriggerType = 'open-overlay' | 'close-overlay';
|
export type BlockVariationTriggerType = 'open-overlay' | 'close-overlay';
|
||||||
|
|
||||||
export type BlockAttributes = {
|
export type BlockAttributes = {
|
||||||
navigationStyle: 'label-and-icon' | 'label-only' | 'icon-only';
|
navigationStyle: 'label-and-icon' | 'label-only' | 'icon-only';
|
||||||
buttonStyle: string;
|
buttonStyle: string;
|
||||||
iconSize?: number;
|
iconSize?: number;
|
||||||
overlayMode: ProductFiltersBlockOverlayAttributeOptions;
|
|
||||||
triggerType: BlockVariationTriggerType;
|
triggerType: BlockVariationTriggerType;
|
||||||
overlayIcon: string;
|
overlayIcon: string;
|
||||||
style: {
|
style: {
|
||||||
|
|
|
@ -1,15 +1,6 @@
|
||||||
/**
|
|
||||||
* Internal dependencies
|
|
||||||
*/
|
|
||||||
import { BlockOverlayAttribute } from './constants';
|
|
||||||
|
|
||||||
export type BlockOverlayAttributeOptions =
|
|
||||||
( typeof BlockOverlayAttribute )[ keyof typeof BlockOverlayAttribute ];
|
|
||||||
|
|
||||||
export interface BlockAttributes {
|
export interface BlockAttributes {
|
||||||
setAttributes: ( attributes: ProductFiltersBlockAttributes ) => void;
|
setAttributes: ( attributes: ProductFiltersBlockAttributes ) => void;
|
||||||
productId?: string;
|
productId?: string;
|
||||||
overlay: BlockOverlayAttributeOptions;
|
|
||||||
overlayIcon:
|
overlayIcon:
|
||||||
| 'filter-icon-1'
|
| 'filter-icon-1'
|
||||||
| 'filter-icon-2'
|
| 'filter-icon-2'
|
||||||
|
|
|
@ -1,305 +0,0 @@
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { test, expect } from '@woocommerce/e2e-utils';
|
|
||||||
|
|
||||||
const templatePartData = {
|
|
||||||
selectors: {
|
|
||||||
frontend: {},
|
|
||||||
editor: {
|
|
||||||
blocks: {
|
|
||||||
activeFilters: {
|
|
||||||
title: 'Active (Experimental)',
|
|
||||||
blockLabel: 'Block: Active (Experimental)',
|
|
||||||
},
|
|
||||||
productFilters: {
|
|
||||||
title: 'Product Filters (Experimental)',
|
|
||||||
blockLabel: 'Block: Product Filters (Experimental)',
|
|
||||||
},
|
|
||||||
filterOptions: {
|
|
||||||
title: 'Filter Options',
|
|
||||||
blockLabel: 'Block: Filter Options',
|
|
||||||
},
|
|
||||||
productFiltersOverlayNavigation: {
|
|
||||||
title: 'Overlay Navigation (Experimental)',
|
|
||||||
name: 'woocommerce/product-filters-overlay-navigation',
|
|
||||||
blockLabel: 'Block: Overlay Navigation (Experimental)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
slug: 'product-filters',
|
|
||||||
productPage: '/product/hoodie/',
|
|
||||||
};
|
|
||||||
|
|
||||||
test.describe( 'Filters Overlay Template Part', () => {
|
|
||||||
test.beforeEach( async ( { admin, requestUtils } ) => {
|
|
||||||
await requestUtils.activatePlugin(
|
|
||||||
'woocommerce-blocks-test-enable-experimental-features'
|
|
||||||
);
|
|
||||||
await admin.visitSiteEditor( {
|
|
||||||
postType: 'wp_template_part',
|
|
||||||
postId: 'woocommerce/woocommerce//product-filters-overlay',
|
|
||||||
canvas: 'edit',
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
test( 'should be visible in the template parts list', async ( {
|
|
||||||
page,
|
|
||||||
admin,
|
|
||||||
} ) => {
|
|
||||||
await admin.visitSiteEditor( {
|
|
||||||
postType: 'wp_template_part',
|
|
||||||
} );
|
|
||||||
const block = page
|
|
||||||
.getByLabel( 'Patterns content' )
|
|
||||||
.getByText( 'Filters Overlay' )
|
|
||||||
.and( page.getByRole( 'button' ) );
|
|
||||||
await expect( block ).toBeVisible();
|
|
||||||
} );
|
|
||||||
|
|
||||||
test( 'should render the correct inner blocks', async ( { editor } ) => {
|
|
||||||
const productFiltersTemplatePart = editor.canvas
|
|
||||||
.locator( '[data-type="core/template-part"]' )
|
|
||||||
.filter( {
|
|
||||||
has: editor.canvas.getByLabel(
|
|
||||||
templatePartData.selectors.editor.blocks.productFilters
|
|
||||||
.blockLabel
|
|
||||||
),
|
|
||||||
} );
|
|
||||||
|
|
||||||
await expect( productFiltersTemplatePart ).toBeVisible();
|
|
||||||
} );
|
|
||||||
|
|
||||||
test.describe( 'frontend', () => {
|
|
||||||
test.beforeEach( async ( { admin } ) => {
|
|
||||||
await admin.visitSiteEditor( {
|
|
||||||
postId: `woocommerce/woocommerce//archive-product`,
|
|
||||||
postType: 'wp_template',
|
|
||||||
canvas: 'edit',
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Since we need to overhaul the overlay area, we can skip this test for now.
|
|
||||||
// eslint-disable-next-line playwright/no-skipped-test
|
|
||||||
test.skip( 'should open and close the dialog when clicking on the Product Filters Overlay Navigation block', async ( {
|
|
||||||
editor,
|
|
||||||
page,
|
|
||||||
frontendUtils,
|
|
||||||
} ) => {
|
|
||||||
await editor.setContent( '' );
|
|
||||||
await editor.openGlobalBlockInserter();
|
|
||||||
await page
|
|
||||||
.getByText(
|
|
||||||
templatePartData.selectors.editor.blocks.productFilters
|
|
||||||
.title
|
|
||||||
)
|
|
||||||
.click();
|
|
||||||
const block = editor.canvas.getByLabel(
|
|
||||||
templatePartData.selectors.editor.blocks.productFilters
|
|
||||||
.blockLabel
|
|
||||||
);
|
|
||||||
await expect( block ).toBeVisible();
|
|
||||||
|
|
||||||
// This forces the list view to show the inner blocks of the Product Filters template part.
|
|
||||||
await editor.canvas
|
|
||||||
.getByLabel(
|
|
||||||
templatePartData.selectors.editor.blocks.activeFilters
|
|
||||||
.blockLabel
|
|
||||||
)
|
|
||||||
.click();
|
|
||||||
|
|
||||||
await editor.openDocumentSettingsSidebar();
|
|
||||||
await page.getByLabel( 'Document Overview' ).click();
|
|
||||||
await page
|
|
||||||
.getByRole( 'link', {
|
|
||||||
name: templatePartData.selectors.editor.blocks
|
|
||||||
.productFilters.title,
|
|
||||||
} )
|
|
||||||
.nth( 1 )
|
|
||||||
.click();
|
|
||||||
|
|
||||||
const layoutSettings = editor.page.getByText(
|
|
||||||
'OverlayNeverMobileAlways'
|
|
||||||
);
|
|
||||||
await layoutSettings.getByLabel( 'Always' ).click();
|
|
||||||
await editor.page
|
|
||||||
.getByRole( 'link', {
|
|
||||||
name: templatePartData.selectors.editor.blocks
|
|
||||||
.productFiltersOverlayNavigation.title,
|
|
||||||
} )
|
|
||||||
.click();
|
|
||||||
|
|
||||||
await editor.saveSiteEditorEntities( {
|
|
||||||
isOnlyCurrentEntityDirty: false,
|
|
||||||
} );
|
|
||||||
|
|
||||||
await page.goto( '/shop/' );
|
|
||||||
|
|
||||||
const productFiltersOverlayNavigation = (
|
|
||||||
await frontendUtils.getBlockByName(
|
|
||||||
templatePartData.selectors.editor.blocks
|
|
||||||
.productFiltersOverlayNavigation.name
|
|
||||||
)
|
|
||||||
).filter( {
|
|
||||||
has: page.locator( ':visible' ),
|
|
||||||
} );
|
|
||||||
|
|
||||||
await expect( productFiltersOverlayNavigation ).toBeVisible();
|
|
||||||
|
|
||||||
await page
|
|
||||||
.locator( '.wc-block-product-filters-overlay-navigation' )
|
|
||||||
.first()
|
|
||||||
.click();
|
|
||||||
|
|
||||||
const productFiltersDialog = page.locator(
|
|
||||||
'.wc-block-product-filters--dialog-open'
|
|
||||||
);
|
|
||||||
|
|
||||||
await expect( productFiltersDialog ).toBeVisible();
|
|
||||||
|
|
||||||
const productFiltersDialogCloseButton = (
|
|
||||||
await frontendUtils.getBlockByName(
|
|
||||||
templatePartData.selectors.editor.blocks
|
|
||||||
.productFiltersOverlayNavigation.name
|
|
||||||
)
|
|
||||||
).filter( { hasText: 'Close' } );
|
|
||||||
|
|
||||||
await expect( productFiltersDialogCloseButton ).toBeVisible();
|
|
||||||
|
|
||||||
await productFiltersDialogCloseButton.click();
|
|
||||||
|
|
||||||
await expect( productFiltersDialog ).toBeHidden();
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Since we need to overhaul the overlay area, we can skip this test for now.
|
|
||||||
// eslint-disable-next-line playwright/no-skipped-test
|
|
||||||
test.skip( 'should hide Product Filters Overlay Navigation block when the Overlay mode is set to `Never`', async ( {
|
|
||||||
editor,
|
|
||||||
page,
|
|
||||||
frontendUtils,
|
|
||||||
} ) => {
|
|
||||||
await editor.setContent( '' );
|
|
||||||
await editor.openGlobalBlockInserter();
|
|
||||||
await page
|
|
||||||
.getByText(
|
|
||||||
templatePartData.selectors.editor.blocks.productFilters
|
|
||||||
.title
|
|
||||||
)
|
|
||||||
.click();
|
|
||||||
const block = editor.canvas.getByLabel(
|
|
||||||
templatePartData.selectors.editor.blocks.productFilters
|
|
||||||
.blockLabel
|
|
||||||
);
|
|
||||||
await expect( block ).toBeVisible();
|
|
||||||
|
|
||||||
// This forces the list view to show the inner blocks of the Product Filters template part.
|
|
||||||
await editor.canvas
|
|
||||||
.getByLabel(
|
|
||||||
templatePartData.selectors.editor.blocks.activeFilters
|
|
||||||
.blockLabel
|
|
||||||
)
|
|
||||||
.click();
|
|
||||||
|
|
||||||
await editor.openDocumentSettingsSidebar();
|
|
||||||
await page.getByLabel( 'Document Overview' ).click();
|
|
||||||
await page
|
|
||||||
.getByRole( 'link', {
|
|
||||||
name: templatePartData.selectors.editor.blocks
|
|
||||||
.productFilters.title,
|
|
||||||
} )
|
|
||||||
.nth( 1 )
|
|
||||||
.click();
|
|
||||||
|
|
||||||
const layoutSettings = editor.page.getByText(
|
|
||||||
'OverlayNeverMobileAlways'
|
|
||||||
);
|
|
||||||
await layoutSettings.getByLabel( 'Never' ).click();
|
|
||||||
|
|
||||||
await editor.saveSiteEditorEntities( {
|
|
||||||
isOnlyCurrentEntityDirty: true,
|
|
||||||
} );
|
|
||||||
|
|
||||||
await page.goto( '/shop/' );
|
|
||||||
|
|
||||||
const productFiltersOverlayNavigation = (
|
|
||||||
await frontendUtils.getBlockByName(
|
|
||||||
templatePartData.selectors.editor.blocks
|
|
||||||
.productFiltersOverlayNavigation.name
|
|
||||||
)
|
|
||||||
).filter( {
|
|
||||||
has: page.locator( ':visible' ),
|
|
||||||
} );
|
|
||||||
|
|
||||||
await expect( productFiltersOverlayNavigation ).toBeHidden();
|
|
||||||
} );
|
|
||||||
|
|
||||||
// Since we need to overhaul the overlay area, we can skip this test for now.
|
|
||||||
// eslint-disable-next-line playwright/no-skipped-test
|
|
||||||
test.skip( 'should hide Product Filters Overlay Navigation block when the Overlay mode is set to `Mobile` and user is on desktop', async ( {
|
|
||||||
editor,
|
|
||||||
page,
|
|
||||||
frontendUtils,
|
|
||||||
} ) => {
|
|
||||||
await editor.setContent( '' );
|
|
||||||
await editor.openGlobalBlockInserter();
|
|
||||||
await page
|
|
||||||
.getByText(
|
|
||||||
templatePartData.selectors.editor.blocks.productFilters
|
|
||||||
.title
|
|
||||||
)
|
|
||||||
.click();
|
|
||||||
const block = editor.canvas.getByLabel(
|
|
||||||
templatePartData.selectors.editor.blocks.productFilters
|
|
||||||
.blockLabel
|
|
||||||
);
|
|
||||||
await expect( block ).toBeVisible();
|
|
||||||
|
|
||||||
// This forces the list view to show the inner blocks of the Product Filters template part.
|
|
||||||
await editor.canvas
|
|
||||||
.getByLabel(
|
|
||||||
templatePartData.selectors.editor.blocks.activeFilters
|
|
||||||
.blockLabel
|
|
||||||
)
|
|
||||||
.click();
|
|
||||||
|
|
||||||
await editor.openDocumentSettingsSidebar();
|
|
||||||
await page.getByLabel( 'Document Overview' ).click();
|
|
||||||
await page
|
|
||||||
.getByRole( 'link', {
|
|
||||||
name: templatePartData.selectors.editor.blocks
|
|
||||||
.productFilters.title,
|
|
||||||
} )
|
|
||||||
.nth( 1 )
|
|
||||||
.click();
|
|
||||||
|
|
||||||
const layoutSettings = editor.page.getByText(
|
|
||||||
'OverlayNeverMobileAlways'
|
|
||||||
);
|
|
||||||
await layoutSettings.getByLabel( 'Mobile' ).click();
|
|
||||||
await editor.page
|
|
||||||
.getByRole( 'link', {
|
|
||||||
name: templatePartData.selectors.editor.blocks
|
|
||||||
.productFiltersOverlayNavigation.title,
|
|
||||||
} )
|
|
||||||
.click();
|
|
||||||
|
|
||||||
await editor.saveSiteEditorEntities( {
|
|
||||||
isOnlyCurrentEntityDirty: false,
|
|
||||||
} );
|
|
||||||
|
|
||||||
await page.goto( '/shop/' );
|
|
||||||
|
|
||||||
const productFiltersOverlayNavigation = (
|
|
||||||
await frontendUtils.getBlockByName(
|
|
||||||
templatePartData.selectors.editor.blocks
|
|
||||||
.productFiltersOverlayNavigation.name
|
|
||||||
)
|
|
||||||
).filter( {
|
|
||||||
has: page.locator( ':visible' ),
|
|
||||||
} );
|
|
||||||
|
|
||||||
await expect( productFiltersOverlayNavigation ).toBeHidden();
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -1,80 +0,0 @@
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { test, expect, BlockData } from '@woocommerce/e2e-utils';
|
|
||||||
|
|
||||||
const blockData: BlockData = {
|
|
||||||
name: 'Product Filters (Experimental)',
|
|
||||||
slug: 'woocommerce/product-filters',
|
|
||||||
mainClass: '.wp-block-woocommerce-product-filters',
|
|
||||||
selectors: {
|
|
||||||
editor: {
|
|
||||||
block: '.wp-block-woocommerce-product-filters',
|
|
||||||
},
|
|
||||||
frontend: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
test.describe( 'Product Filters Template Part', () => {
|
|
||||||
test.beforeEach( async ( { admin, requestUtils } ) => {
|
|
||||||
await requestUtils.activatePlugin(
|
|
||||||
'woocommerce-blocks-test-enable-experimental-features'
|
|
||||||
);
|
|
||||||
await admin.visitSiteEditor( {
|
|
||||||
postType: 'wp_template_part',
|
|
||||||
postId: 'woocommerce/woocommerce//product-filters',
|
|
||||||
canvas: 'edit',
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
test( 'should be visible in the templates part list', async ( {
|
|
||||||
page,
|
|
||||||
admin,
|
|
||||||
} ) => {
|
|
||||||
await admin.visitSiteEditor( {
|
|
||||||
postType: 'wp_template_part',
|
|
||||||
} );
|
|
||||||
const templatePart = page
|
|
||||||
.getByLabel( 'Patterns content' )
|
|
||||||
.getByText( 'Product Filters (Experimental)', { exact: true } )
|
|
||||||
.and( page.getByRole( 'button' ) );
|
|
||||||
await expect( templatePart ).toBeVisible();
|
|
||||||
} );
|
|
||||||
|
|
||||||
test( 'should render the Product Filters block', async ( { editor } ) => {
|
|
||||||
const productFiltersBlock = editor.canvas.getByLabel(
|
|
||||||
`Block: ${ blockData.name }`
|
|
||||||
);
|
|
||||||
await expect( productFiltersBlock ).toBeVisible();
|
|
||||||
} );
|
|
||||||
|
|
||||||
test( 'Filters > can be added multiple times', async ( { editor } ) => {
|
|
||||||
const block = editor.canvas.getByLabel( `Block: ${ blockData.name }` );
|
|
||||||
await expect( block ).toBeVisible();
|
|
||||||
|
|
||||||
const searchTerms = [ 'Color (Experimental)', 'Active (Experimental)' ];
|
|
||||||
|
|
||||||
for ( const filter of searchTerms ) {
|
|
||||||
await editor.selectBlocks( blockData.selectors.editor.block );
|
|
||||||
|
|
||||||
const addBlock = block.getByRole( 'button', {
|
|
||||||
name: 'Add block',
|
|
||||||
} );
|
|
||||||
|
|
||||||
await addBlock.click();
|
|
||||||
|
|
||||||
await editor.page.getByPlaceholder( 'Search' ).fill( filter );
|
|
||||||
|
|
||||||
const searchResult = editor.page.getByRole( 'option', {
|
|
||||||
name: filter,
|
|
||||||
} );
|
|
||||||
await expect( searchResult ).toBeVisible();
|
|
||||||
|
|
||||||
await searchResult.click();
|
|
||||||
|
|
||||||
const _locator = `[aria-label="Block: ${ filter }"]`;
|
|
||||||
|
|
||||||
await expect( editor.canvas.locator( _locator ) ).toHaveCount( 2 );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
} );
|
|
|
@ -183,63 +183,6 @@ test.describe( `${ blockData.name }`, () => {
|
||||||
).toBeVisible();
|
).toBeVisible();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
test( 'should display the correct inspector setting controls', async ( {
|
|
||||||
editor,
|
|
||||||
pageObject,
|
|
||||||
} ) => {
|
|
||||||
await pageObject.addProductFiltersBlock( { cleanContent: true } );
|
|
||||||
|
|
||||||
const filtersBlock = editor.canvas.getByLabel(
|
|
||||||
blockData.selectors.editor.blocks.filters.label
|
|
||||||
);
|
|
||||||
await expect( filtersBlock ).toBeVisible();
|
|
||||||
|
|
||||||
const overlayBlock = editor.canvas.getByLabel(
|
|
||||||
blockData.selectors.editor.blocks.overlay.label
|
|
||||||
);
|
|
||||||
|
|
||||||
// Overlay mode is set to 'Never' by default so the block should be hidden
|
|
||||||
await expect( overlayBlock ).toBeHidden();
|
|
||||||
|
|
||||||
await editor.openDocumentSettingsSidebar();
|
|
||||||
|
|
||||||
// Layout settings
|
|
||||||
await expect(
|
|
||||||
editor.page.getByText( 'LayoutJustificationOrientation' )
|
|
||||||
).toBeVisible();
|
|
||||||
|
|
||||||
// Overlay settings
|
|
||||||
const overlayModeSettings = [ 'Never', 'Mobile', 'Always' ];
|
|
||||||
|
|
||||||
await expect( editor.page.getByText( 'Overlay' ) ).toBeVisible();
|
|
||||||
|
|
||||||
for ( const mode of overlayModeSettings ) {
|
|
||||||
await expect( editor.page.getByText( mode ) ).toBeVisible();
|
|
||||||
}
|
|
||||||
|
|
||||||
await editor.page.getByLabel( 'Never' ).click();
|
|
||||||
|
|
||||||
await expect( editor.page.getByText( 'Edit overlay' ) ).toBeHidden();
|
|
||||||
|
|
||||||
await expect( overlayBlock ).toBeHidden();
|
|
||||||
|
|
||||||
await editor.page.getByLabel( 'Mobile' ).click();
|
|
||||||
|
|
||||||
await expect( editor.page.getByText( 'Edit overlay' ) ).toBeVisible();
|
|
||||||
|
|
||||||
await expect( overlayBlock ).toBeVisible();
|
|
||||||
|
|
||||||
await editor.page.getByLabel( 'Always' ).click();
|
|
||||||
|
|
||||||
await expect( editor.page.getByText( 'Edit overlay' ) ).toBeVisible();
|
|
||||||
|
|
||||||
await expect( overlayBlock ).toBeVisible();
|
|
||||||
|
|
||||||
await editor.page.getByLabel( 'Never' ).click();
|
|
||||||
|
|
||||||
await expect( overlayBlock ).toBeHidden();
|
|
||||||
} );
|
|
||||||
|
|
||||||
test( 'Layout > default to vertical stretch', async ( {
|
test( 'Layout > default to vertical stretch', async ( {
|
||||||
editor,
|
editor,
|
||||||
pageObject,
|
pageObject,
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
<svg width="248" height="140" viewBox="0 0 248 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g filter="url(#filter0_dd_1397_9617)">
|
|
||||||
<rect width="248" height="140" rx="2" fill="white" shape-rendering="crispEdges"/>
|
|
||||||
<rect x="84" y="15" width="80" height="8" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="84" y="31" width="56" height="6" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="84" y="41" width="56" height="16" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="84" y="65" width="80" height="6" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="84" y="75" width="31" height="16" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="84" y="99" width="70" height="6" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="84" y="109" width="56" height="16" rx="1" fill="#E0E0E0"/>
|
|
||||||
<path d="M230.773 17.8336L234.485 21.5459L235.546 20.4853L231.834 16.773L235.546 13.0607L234.485 12L230.773 15.7123L227.061 12L226 13.0607L229.712 16.773L226 20.4853L227.061 21.5459L230.773 17.8336Z" fill="#BBBBBB"/>
|
|
||||||
</g>
|
|
||||||
<rect x="0.5" y="0.5" width="247" height="139" rx="1.5" stroke="#DDDDDD"/>
|
|
||||||
<defs>
|
|
||||||
<filter id="filter0_dd_1397_9617" x="-9" y="-6" width="266" height="158" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
||||||
<feOffset dy="3"/>
|
|
||||||
<feGaussianBlur stdDeviation="4.5"/>
|
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0"/>
|
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1397_9617"/>
|
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
||||||
<feOffset dy="1"/>
|
|
||||||
<feGaussianBlur stdDeviation="1.5"/>
|
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
|
|
||||||
<feBlend mode="normal" in2="effect1_dropShadow_1397_9617" result="effect2_dropShadow_1397_9617"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_1397_9617" result="shape"/>
|
|
||||||
</filter>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.0 KiB |
|
@ -1,38 +0,0 @@
|
||||||
<svg width="248" height="140" viewBox="0 0 248 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0_481_510179)">
|
|
||||||
<rect width="248" height="140" rx="2" fill="black" fill-opacity="0.05"/>
|
|
||||||
<g filter="url(#filter0_dd_481_510179)">
|
|
||||||
<path d="M0 0H146C147.105 0 148 0.895431 148 2V138C148 139.105 147.105 140 146 140H0V0Z" fill="white"/>
|
|
||||||
<rect x="24" y="15" width="80" height="8" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="24" y="31" width="56" height="6" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="24" y="41" width="56" height="16" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="24" y="65" width="80" height="6" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="24" y="75" width="31" height="16" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="24" y="99" width="70" height="6" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="24" y="109" width="56" height="16" rx="1" fill="#E0E0E0"/>
|
|
||||||
<path d="M130.773 17.8336L134.485 21.5459L135.546 20.4853L131.834 16.773L135.546 13.0607L134.485 12L130.773 15.7123L127.061 12L126 13.0607L129.712 16.773L126 20.4853L127.061 21.5459L130.773 17.8336Z" fill="#BBBBBB"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<rect x="0.5" y="0.5" width="247" height="139" rx="1.5" stroke="#DDDDDD"/>
|
|
||||||
<defs>
|
|
||||||
<filter id="filter0_dd_481_510179" x="-9" y="-6" width="166" height="158" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
||||||
<feOffset dy="3"/>
|
|
||||||
<feGaussianBlur stdDeviation="4.5"/>
|
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0"/>
|
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_481_510179"/>
|
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
||||||
<feOffset dy="1"/>
|
|
||||||
<feGaussianBlur stdDeviation="1.5"/>
|
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
|
|
||||||
<feBlend mode="normal" in2="effect1_dropShadow_481_510179" result="effect2_dropShadow_481_510179"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_481_510179" result="shape"/>
|
|
||||||
</filter>
|
|
||||||
<clipPath id="clip0_481_510179">
|
|
||||||
<rect width="248" height="140" rx="2" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.3 KiB |
|
@ -1,38 +0,0 @@
|
||||||
<svg width="248" height="140" viewBox="0 0 248 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0_1429_82805)">
|
|
||||||
<rect width="248" height="140" rx="2" fill="black" fill-opacity="0.05"/>
|
|
||||||
<g filter="url(#filter0_dd_1429_82805)">
|
|
||||||
<path d="M100 0H246C247.105 0 248 0.895431 248 2V138C248 139.105 247.105 140 246 140H100V0Z" fill="white"/>
|
|
||||||
<rect x="143.996" y="15" width="80" height="8" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="143.996" y="31" width="56" height="6" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="143.996" y="41" width="56" height="16" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="143.996" y="65" width="80" height="6" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="143.996" y="75" width="31" height="16" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="143.996" y="99" width="70" height="6" rx="1" fill="#E0E0E0"/>
|
|
||||||
<rect x="143.996" y="109" width="56" height="16" rx="1" fill="#E0E0E0"/>
|
|
||||||
<path d="M117.223 17.8336L120.935 21.5459L121.996 20.4853L118.284 16.773L121.996 13.0607L120.935 12L117.223 15.7123L113.511 12L112.45 13.0607L116.163 16.773L112.45 20.4853L113.511 21.5459L117.223 17.8336Z" fill="#BBBBBB"/>
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
<rect x="0.5" y="0.5" width="247" height="139" rx="1.5" stroke="#DDDDDD"/>
|
|
||||||
<defs>
|
|
||||||
<filter id="filter0_dd_1429_82805" x="91" y="-6" width="166" height="158" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
||||||
<feOffset dy="3"/>
|
|
||||||
<feGaussianBlur stdDeviation="4.5"/>
|
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0"/>
|
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1429_82805"/>
|
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
||||||
<feOffset dy="1"/>
|
|
||||||
<feGaussianBlur stdDeviation="1.5"/>
|
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
|
|
||||||
<feBlend mode="normal" in2="effect1_dropShadow_1429_82805" result="effect2_dropShadow_1429_82805"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_1429_82805" result="shape"/>
|
|
||||||
</filter>
|
|
||||||
<clipPath id="clip0_1429_82805">
|
|
||||||
<rect width="248" height="140" rx="2" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.3 KiB |
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: tweak
|
||||||
|
Comment: Experimental block - remove template parts
|
||||||
|
|
|
@ -17,8 +17,6 @@ use Automattic\WooCommerce\Blocks\Templates\ProductCategoryTemplate;
|
||||||
use Automattic\WooCommerce\Blocks\Templates\ProductTagTemplate;
|
use Automattic\WooCommerce\Blocks\Templates\ProductTagTemplate;
|
||||||
use Automattic\WooCommerce\Blocks\Templates\ProductSearchResultsTemplate;
|
use Automattic\WooCommerce\Blocks\Templates\ProductSearchResultsTemplate;
|
||||||
use Automattic\WooCommerce\Blocks\Templates\SingleProductTemplate;
|
use Automattic\WooCommerce\Blocks\Templates\SingleProductTemplate;
|
||||||
use Automattic\WooCommerce\Blocks\Templates\ProductFiltersTemplate;
|
|
||||||
use Automattic\WooCommerce\Blocks\Templates\ProductFiltersOverlayTemplate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BlockTemplatesRegistry class.
|
* BlockTemplatesRegistry class.
|
||||||
|
@ -61,11 +59,6 @@ class BlockTemplatesRegistry {
|
||||||
MiniCartTemplate::SLUG => new MiniCartTemplate(),
|
MiniCartTemplate::SLUG => new MiniCartTemplate(),
|
||||||
CheckoutHeaderTemplate::SLUG => new CheckoutHeaderTemplate(),
|
CheckoutHeaderTemplate::SLUG => new CheckoutHeaderTemplate(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( Features::is_enabled( 'experimental-blocks' ) ) {
|
|
||||||
$template_parts[ ProductFiltersTemplate::SLUG ] = new ProductFiltersTemplate();
|
|
||||||
$template_parts[ ProductFiltersOverlayTemplate::SLUG ] = new ProductFiltersOverlayTemplate();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$template_parts = array();
|
$template_parts = array();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Automattic\WooCommerce\Blocks\BlockTypes;
|
namespace Automattic\WooCommerce\Blocks\BlockTypes;
|
||||||
|
|
||||||
use Automattic\WooCommerce\Blocks\Utils\BlockTemplateUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ProductFilters class.
|
* ProductFilters class.
|
||||||
*/
|
*/
|
||||||
|
@ -40,90 +38,6 @@ class ProductFilters extends AbstractBlock {
|
||||||
$this->asset_data_registry->add( 'isWidgetEditor', 'widgets.php' === $pagenow || 'customize.php' === $pagenow );
|
$this->asset_data_registry->add( 'isWidgetEditor', 'widgets.php' === $pagenow || 'customize.php' === $pagenow );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the dialog content.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function render_dialog() {
|
|
||||||
$template_part = BlockTemplateUtils::get_template_part( 'product-filters-overlay' );
|
|
||||||
|
|
||||||
$html = $this->render_template_part( $template_part );
|
|
||||||
|
|
||||||
$html = strtr(
|
|
||||||
'<dialog hidden role="dialog" aria-modal="true">
|
|
||||||
{{html}}
|
|
||||||
</dialog>',
|
|
||||||
array(
|
|
||||||
'{{html}}' => $html,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
$p = new \WP_HTML_Tag_Processor( $html );
|
|
||||||
if ( $p->next_tag() ) {
|
|
||||||
$p->set_attribute( 'data-wc-interactive', wp_json_encode( array( 'namespace' => 'woocommerce/product-filters' ), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP ) );
|
|
||||||
$p->set_attribute( 'data-wc-bind--hidden', '!state.isDialogOpen' );
|
|
||||||
$p->set_attribute( 'data-wc-class--wc-block-product-filters--dialog-open', 'state.isDialogOpen' );
|
|
||||||
$p->set_attribute( 'data-wc-class--wc-block-product-filters--with-admin-bar', 'context.hasPageWithWordPressAdminBar' );
|
|
||||||
$html = $p->get_updated_html();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is used to render the template part. For each template part, we parse the blocks and render them.
|
|
||||||
*
|
|
||||||
* @param string $template_part The template part to render.
|
|
||||||
* @return string The rendered template part.
|
|
||||||
*/
|
|
||||||
protected function render_template_part( $template_part ) {
|
|
||||||
$parsed_blocks = parse_blocks( $template_part );
|
|
||||||
$wrapper_template_part_block = $parsed_blocks[0];
|
|
||||||
$html = $wrapper_template_part_block['innerHTML'];
|
|
||||||
$target_div = '</div>';
|
|
||||||
|
|
||||||
$template_part_content_html = array_reduce(
|
|
||||||
$wrapper_template_part_block['innerBlocks'],
|
|
||||||
function ( $carry, $item ) {
|
|
||||||
if ( 'core/template-part' === $item['blockName'] ) {
|
|
||||||
$inner_template_part = BlockTemplateUtils::get_template_part( $item['attrs']['slug'] );
|
|
||||||
$inner_template_part_content_html = $this->render_template_part( $inner_template_part );
|
|
||||||
|
|
||||||
return $carry . $inner_template_part_content_html;
|
|
||||||
}
|
|
||||||
return $carry . render_block( $item );
|
|
||||||
},
|
|
||||||
''
|
|
||||||
);
|
|
||||||
|
|
||||||
$html = str_replace( $target_div, $template_part_content_html . $target_div, $html );
|
|
||||||
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inject dialog into the product filters HTML.
|
|
||||||
*
|
|
||||||
* @param string $product_filters_html The Product Filters HTML.
|
|
||||||
* @param string $dialog_html The dialog HTML.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function inject_dialog( $product_filters_html, $dialog_html ) {
|
|
||||||
// Find the position of the last </div>.
|
|
||||||
$pos = strrpos( $product_filters_html, '</div>' );
|
|
||||||
|
|
||||||
if ( $pos ) {
|
|
||||||
// Inject the dialog_html at the correct position.
|
|
||||||
$html = substr_replace( $product_filters_html, $dialog_html, $pos, 0 );
|
|
||||||
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $product_filters_html;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Include and render the block.
|
* Include and render the block.
|
||||||
*
|
*
|
||||||
|
@ -151,13 +65,6 @@ class ProductFilters extends AbstractBlock {
|
||||||
$tags->set_attribute( 'data-wc-navigation-id', $this->generate_navigation_id( $block ) );
|
$tags->set_attribute( 'data-wc-navigation-id', $this->generate_navigation_id( $block ) );
|
||||||
$tags->set_attribute( 'data-wc-watch', 'callbacks.maybeNavigate' );
|
$tags->set_attribute( 'data-wc-watch', 'callbacks.maybeNavigate' );
|
||||||
|
|
||||||
if (
|
|
||||||
'always' === $attributes['overlay'] ||
|
|
||||||
( 'mobile' === $attributes['overlay'] && wp_is_mobile() )
|
|
||||||
) {
|
|
||||||
return $this->inject_dialog( $tags->get_updated_html(), $this->render_dialog() );
|
|
||||||
}
|
|
||||||
|
|
||||||
return $tags->get_updated_html();
|
return $tags->get_updated_html();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,6 @@ class ProductFiltersOverlayNavigation extends AbstractBlock {
|
||||||
'class' => 'wc-block-product-filters-overlay-navigation',
|
'class' => 'wc-block-product-filters-overlay-navigation',
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$overlay_mode = isset( $block->context['woocommerce/product-filters/overlay'] ) ? $block->context['woocommerce/product-filters/overlay'] : 'never';
|
|
||||||
|
|
||||||
if ( 'open-overlay' === $attributes['triggerType'] && ( 'never' === $overlay_mode || ( ! wp_is_mobile() && 'mobile' === $overlay_mode ) ) ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$html = strtr(
|
$html = strtr(
|
||||||
'<div {{wrapper_attributes}}>
|
'<div {{wrapper_attributes}}>
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
<?php
|
|
||||||
namespace Automattic\WooCommerce\Blocks\Templates;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ProductFiltersOverlayTemplate class.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
class ProductFiltersOverlayTemplate extends AbstractTemplatePart {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The slug of the template.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
const SLUG = 'product-filters-overlay';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The template part area where the template part belongs.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $template_area = 'uncategorized';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization method.
|
|
||||||
*/
|
|
||||||
public function init() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the title of the template.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function get_template_title() {
|
|
||||||
return _x( 'Filters Overlay', 'Template name', 'woocommerce' );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the description of the template.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function get_template_description() {
|
|
||||||
return __( 'Template used to display the Product Filters Overlay.', 'woocommerce' );
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,95 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
namespace Automattic\WooCommerce\Blocks\Templates;
|
|
||||||
|
|
||||||
use Automattic\WooCommerce\Blocks\Utils\BlockTemplateUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ProductFiltersTemplate class.
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
class ProductFiltersTemplate extends AbstractTemplatePart {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The slug of the template.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
const SLUG = 'product-filters';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The template part area where the template part belongs.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public $template_area = 'uncategorized';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization method.
|
|
||||||
*/
|
|
||||||
public function init() {
|
|
||||||
add_filter( 'get_block_type_variations', array( $this, 'register_block_type_variation' ), 10, 2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the title of the template.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function get_template_title() {
|
|
||||||
return _x( 'Product Filters (Experimental)', 'Template name', 'woocommerce' );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the description of the template.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function get_template_description() {
|
|
||||||
return __(
|
|
||||||
'This is the template part for the product filters displayed on different pages across your store.',
|
|
||||||
'woocommerce'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add variation for this template part to make it available in the block inserter.
|
|
||||||
*
|
|
||||||
* @param array $variations Array of registered variations for a block type.
|
|
||||||
* @param WP_Block_Type $block_type The full block type object.
|
|
||||||
*/
|
|
||||||
public function register_block_type_variation( $variations, $block_type ) {
|
|
||||||
if ( 'core/template-part' !== $block_type->name ) {
|
|
||||||
return $variations;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If template part is modified, Core will pick it up and register a variation
|
|
||||||
// for it. Check if the variation already exists before adding it.
|
|
||||||
foreach ( $variations as $variation ) {
|
|
||||||
if ( ! empty( $variation['attributes']['slug'] ) && 'product-filters' === $variation['attributes']['slug'] ) {
|
|
||||||
return $variations;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$theme = 'woocommerce/woocommerce';
|
|
||||||
// Check if current theme overrides this template part.
|
|
||||||
if ( BlockTemplateUtils::theme_has_template_part( 'product-filters' ) ) {
|
|
||||||
$theme = wp_get_theme()->get( 'TextDomain' );
|
|
||||||
}
|
|
||||||
|
|
||||||
$variations[] = array(
|
|
||||||
'name' => 'file_' . self::SLUG,
|
|
||||||
'title' => $this->get_template_title(),
|
|
||||||
'description' => true,
|
|
||||||
'attributes' => array(
|
|
||||||
'slug' => self::SLUG,
|
|
||||||
'theme' => $theme,
|
|
||||||
'area' => $this->template_area,
|
|
||||||
),
|
|
||||||
'scope' => array( 'inserter' ),
|
|
||||||
'icon' => 'layout',
|
|
||||||
);
|
|
||||||
return $variations;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -319,11 +319,6 @@ class BlockTemplateUtils {
|
||||||
'mini-cart.html',
|
'mini-cart.html',
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( Features::is_enabled( 'experimental-blocks' ) ) {
|
|
||||||
$wp_template_part_filenames[] = 'product-filters.html';
|
|
||||||
$wp_template_part_filenames[] = 'product-filters-overlay.html';
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This may return the blockified directory for wp_templates.
|
* This may return the blockified directory for wp_templates.
|
||||||
* At the moment every template file has a corresponding blockified file.
|
* At the moment every template file has a corresponding blockified file.
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
<!-- wp:woocommerce/product-filters-overlay {"lock":{"move":true,"remove":true}} -->
|
|
||||||
<div class="wp-block-woocommerce-product-filters-overlay wc-block-product-filters-overlay" style="padding-top:1rem;padding-right:1rem;padding-bottom:1rem;padding-left:1rem">
|
|
||||||
<!-- wp:woocommerce/product-filters-overlay-navigation {"triggerType":"close-overlay","lock":{"move":true,"remove":true}} -->
|
|
||||||
<div class="wp-block-woocommerce-product-filters-overlay-navigation alignright wc-block-product-filters-overlay-navigation"></div>
|
|
||||||
<!-- /wp:woocommerce/product-filters-overlay-navigation -->
|
|
||||||
|
|
||||||
<!-- wp:template-part {"slug":"product-filters","theme":"woocommerce/woocommerce","area":"uncategorized","lock":{"move":true,"remove":true}} /--></div>
|
|
||||||
<!-- /wp:woocommerce/product-filters-overlay -->
|
|
|
@ -1,28 +0,0 @@
|
||||||
<!-- wp:woocommerce/product-filters -->
|
|
||||||
<div class="wp-block-woocommerce-product-filters wc-block-product-filters">
|
|
||||||
<!-- wp:heading {"level":2} -->
|
|
||||||
<h2 class="wp-block-heading">Filters</h2>
|
|
||||||
<!-- /wp:heading -->
|
|
||||||
|
|
||||||
<!-- wp:woocommerce/product-filter-active {"displayStyle":"chips"} /-->
|
|
||||||
|
|
||||||
<!-- wp:pattern {"slug":"woocommerce/default-attribute-filter"} /-->
|
|
||||||
|
|
||||||
<!-- wp:buttons {"layout":{"type":"flex"}} -->
|
|
||||||
<div class="wp-block-buttons">
|
|
||||||
<!-- wp:button {"className":"wc-block-product-filters__apply-button","style":{"border":{"width":"0px","style":"none"},"typography":{"textDecoration":"none"},"outline":"none","fontSize":"medium"}} -->
|
|
||||||
<div
|
|
||||||
class="wp-block-button wc-block-product-filters__apply-button"
|
|
||||||
style="text-decoration: none"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="wp-block-button__link wp-element-button"
|
|
||||||
style="border-style: none; border-width: 0px"
|
|
||||||
>Apply</a
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<!-- /wp:button -->
|
|
||||||
</div>
|
|
||||||
<!-- /wp:buttons -->
|
|
||||||
</div>
|
|
||||||
<!-- /wp:woocommerce/product-filters -->
|
|
Loading…
Reference in New Issue