Create Store Breadcrumbs Block (https://github.com/woocommerce/woocommerce-blocks/pull/8222)
* Initial structure for the breadcrumbs block * ditch inline comment * Fine-tune the store breadcrumbs * Disable the breadcrumbs block for regular posts & pages * Update the breadcrumbs block details. * Add tests * rely on sprintf to render the breadcrumb * Ditch usesContext. * Add a link to the breadcrumb editor preview * Disable all pointer-events for the breadcrumb link in the editor preview * Add the align attribute * Use the Disabled component to prevent interactions and update the copy for the block description.
This commit is contained in:
parent
fe0908ae96
commit
9563468dc1
|
@ -0,0 +1,47 @@
|
||||||
|
{
|
||||||
|
"name": "woocommerce/breadcrumbs",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"title": "Store Breadcrumbs",
|
||||||
|
"description": "Enable customers to keep track of their location within the store and navigate back to parent pages.",
|
||||||
|
"category": "woocommerce",
|
||||||
|
"keywords": [ "WooCommerce" ],
|
||||||
|
"textdomain": "woo-gutenberg-products-block",
|
||||||
|
"attributes": {
|
||||||
|
"contentJustification": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"fontSize": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "small"
|
||||||
|
},
|
||||||
|
"align": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "wide"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"supports": {
|
||||||
|
"align": [ "wide", "full" ],
|
||||||
|
"color": {
|
||||||
|
"background": false,
|
||||||
|
"link": true,
|
||||||
|
"__experimentalDefaultControls": {
|
||||||
|
"text": true,
|
||||||
|
"link": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"html": false,
|
||||||
|
"typography": {
|
||||||
|
"fontSize": true,
|
||||||
|
"lineHeight": true,
|
||||||
|
"__experimentalFontFamily": true,
|
||||||
|
"__experimentalFontStyle": true,
|
||||||
|
"__experimentalFontWeight": true,
|
||||||
|
"__experimentalTextTransform": true,
|
||||||
|
"__experimentalDefaultControls": {
|
||||||
|
"fontSize": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"apiVersion": 2,
|
||||||
|
"$schema": "https://schemas.wp.org/trunk/block.json"
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { useBlockProps } from '@wordpress/block-editor';
|
||||||
|
import { Disabled } from '@wordpress/components';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
|
||||||
|
export interface Attributes {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Edit = () => {
|
||||||
|
const blockProps = useBlockProps( {
|
||||||
|
className: 'woocommerce wc-block-breadcrumbs',
|
||||||
|
} );
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div { ...blockProps }>
|
||||||
|
<Disabled>
|
||||||
|
<a href="/">
|
||||||
|
{ __( 'Breadcrumbs', 'woo-gutenberg-products-block' ) }
|
||||||
|
</a>
|
||||||
|
{ __( ' / Navigation / Path', 'woo-gutenberg-products-block' ) }
|
||||||
|
</Disabled>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Edit;
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { registerBlockType } from '@wordpress/blocks';
|
||||||
|
import { Icon, queryPagination } from '@wordpress/icons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import metadata from './block.json';
|
||||||
|
import edit from './edit';
|
||||||
|
|
||||||
|
registerBlockType( metadata, {
|
||||||
|
icon: {
|
||||||
|
src: (
|
||||||
|
<Icon
|
||||||
|
icon={ queryPagination }
|
||||||
|
className="wc-block-editor-components-block-icon"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
attributes: {
|
||||||
|
...metadata.attributes,
|
||||||
|
},
|
||||||
|
edit,
|
||||||
|
save() {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
} );
|
|
@ -0,0 +1,3 @@
|
||||||
|
.woocommerce.wc-block-breadcrumbs {
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ const blocks = {
|
||||||
customDir: 'reviews/all-reviews',
|
customDir: 'reviews/all-reviews',
|
||||||
},
|
},
|
||||||
'attribute-filter': {},
|
'attribute-filter': {},
|
||||||
|
breadcrumbs: {},
|
||||||
cart: {},
|
cart: {},
|
||||||
'catalog-sorting': {},
|
'catalog-sorting': {},
|
||||||
checkout: {},
|
checkout: {},
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Automattic\WooCommerce\Blocks\BlockTypes;
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CatalogSorting class.
|
||||||
|
*/
|
||||||
|
class Breadcrumbs extends AbstractBlock {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block name.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $block_name = 'breadcrumbs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the block.
|
||||||
|
*
|
||||||
|
* @param array $attributes Block attributes.
|
||||||
|
* @param string $content Block content.
|
||||||
|
* @param WP_Block $block Block instance.
|
||||||
|
*
|
||||||
|
* @return string | void Rendered block output.
|
||||||
|
*/
|
||||||
|
protected function render( $attributes, $content, $block ) {
|
||||||
|
ob_start();
|
||||||
|
woocommerce_breadcrumb();
|
||||||
|
$breadcrumb = ob_get_clean();
|
||||||
|
|
||||||
|
if ( ! $breadcrumb ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$classname = $attributes['className'] ?? '';
|
||||||
|
$classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes );
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'<div class="woocommerce wc-block-breadcrumbs %1$s %2$s" style="%3$s">%4$s</div>',
|
||||||
|
esc_attr( $classes_and_styles['classes'] ),
|
||||||
|
esc_attr( $classname ),
|
||||||
|
esc_attr( $classes_and_styles['styles'] ),
|
||||||
|
$breadcrumb
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the frontend script handle for this block type.
|
||||||
|
*
|
||||||
|
* @param string $key Data to get, or default to everything.
|
||||||
|
*/
|
||||||
|
protected function get_block_type_script( $key = null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -168,6 +168,7 @@ final class BlockTypesController {
|
||||||
'AllProducts',
|
'AllProducts',
|
||||||
'AllReviews',
|
'AllReviews',
|
||||||
'AttributeFilter',
|
'AttributeFilter',
|
||||||
|
'Breadcrumbs',
|
||||||
'CatalogSorting',
|
'CatalogSorting',
|
||||||
'ClassicTemplate',
|
'ClassicTemplate',
|
||||||
'CustomerAccount',
|
'CustomerAccount',
|
||||||
|
@ -249,6 +250,7 @@ final class BlockTypesController {
|
||||||
$block_types = array_diff(
|
$block_types = array_diff(
|
||||||
$block_types,
|
$block_types,
|
||||||
[
|
[
|
||||||
|
'Breadcrumbs',
|
||||||
'CatalogSorting',
|
'CatalogSorting',
|
||||||
'ClassicTemplate',
|
'ClassicTemplate',
|
||||||
'ProductResultsCount',
|
'ProductResultsCount',
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
canvas,
|
||||||
|
createNewPost,
|
||||||
|
insertBlock,
|
||||||
|
switchUserToAdmin,
|
||||||
|
} from '@wordpress/e2e-test-utils';
|
||||||
|
import { searchForBlock } from '@wordpress/e2e-test-utils/build/inserter';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import {
|
||||||
|
filterCurrentBlocks,
|
||||||
|
goToSiteEditor,
|
||||||
|
useTheme,
|
||||||
|
waitForCanvas,
|
||||||
|
} from '../../utils.js';
|
||||||
|
|
||||||
|
const block = {
|
||||||
|
name: 'Store Breadcrumbs',
|
||||||
|
slug: 'woocommerce/breadcrumbs',
|
||||||
|
class: '.wc-block-breadcrumbs',
|
||||||
|
};
|
||||||
|
|
||||||
|
describe( `${ block.name } Block`, () => {
|
||||||
|
it( 'in can not be inserted in a post', async () => {
|
||||||
|
await switchUserToAdmin();
|
||||||
|
await createNewPost( {
|
||||||
|
postType: 'post',
|
||||||
|
title: block.name,
|
||||||
|
} );
|
||||||
|
await searchForBlock( block.name );
|
||||||
|
expect( page ).toMatch( 'No results found.' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
describe( 'in FSE editor', () => {
|
||||||
|
useTheme( 'emptytheme' );
|
||||||
|
|
||||||
|
beforeEach( async () => {
|
||||||
|
await goToSiteEditor();
|
||||||
|
await waitForCanvas();
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'can be inserted in FSE area', async () => {
|
||||||
|
await insertBlock( block.name );
|
||||||
|
await expect( canvas() ).toMatchElement( block.class );
|
||||||
|
} );
|
||||||
|
|
||||||
|
it( 'can be inserted more than once', async () => {
|
||||||
|
await insertBlock( block.name );
|
||||||
|
await insertBlock( block.name );
|
||||||
|
const foo = await filterCurrentBlocks(
|
||||||
|
( b ) => b.name === block.slug
|
||||||
|
);
|
||||||
|
expect( foo ).toHaveLength( 2 );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
Loading…
Reference in New Issue