From 9563468dc1cfe21bafb241c1b10e3212b3f30698 Mon Sep 17 00:00:00 2001 From: Patricia Hillebrandt Date: Fri, 27 Jan 2023 18:31:13 +0100 Subject: [PATCH] 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. --- .../assets/js/blocks/breadcrumbs/block.json | 47 ++++++++++++++ .../assets/js/blocks/breadcrumbs/edit.tsx | 29 +++++++++ .../assets/js/blocks/breadcrumbs/index.tsx | 29 +++++++++ .../assets/js/blocks/breadcrumbs/style.scss | 3 + .../woocommerce-blocks/bin/webpack-entries.js | 1 + .../src/BlockTypes/Breadcrumbs.php | 57 +++++++++++++++++ .../src/BlockTypesController.php | 2 + .../e2e/specs/backend/breadcrumbs.test.js | 61 +++++++++++++++++++ 8 files changed, 229 insertions(+) create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/block.json create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/edit.tsx create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/index.tsx create mode 100644 plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/style.scss create mode 100644 plugins/woocommerce-blocks/src/BlockTypes/Breadcrumbs.php create mode 100644 plugins/woocommerce-blocks/tests/e2e/specs/backend/breadcrumbs.test.js diff --git a/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/block.json b/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/block.json new file mode 100644 index 00000000000..9a0cd1681a6 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/block.json @@ -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" +} diff --git a/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/edit.tsx b/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/edit.tsx new file mode 100644 index 00000000000..f68daead0d5 --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/edit.tsx @@ -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 ( +
+ + + { __( 'Breadcrumbs', 'woo-gutenberg-products-block' ) } + + { __( ' / Navigation / Path', 'woo-gutenberg-products-block' ) } + +
+ ); +}; + +export default Edit; diff --git a/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/index.tsx b/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/index.tsx new file mode 100644 index 00000000000..3803cf2020a --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/index.tsx @@ -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: ( + + ), + }, + attributes: { + ...metadata.attributes, + }, + edit, + save() { + return null; + }, +} ); diff --git a/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/style.scss b/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/style.scss new file mode 100644 index 00000000000..a455e9008dc --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/blocks/breadcrumbs/style.scss @@ -0,0 +1,3 @@ +.woocommerce.wc-block-breadcrumbs { + font-size: inherit; +} diff --git a/plugins/woocommerce-blocks/bin/webpack-entries.js b/plugins/woocommerce-blocks/bin/webpack-entries.js index 5bdb771020a..46e0e773b92 100644 --- a/plugins/woocommerce-blocks/bin/webpack-entries.js +++ b/plugins/woocommerce-blocks/bin/webpack-entries.js @@ -20,6 +20,7 @@ const blocks = { customDir: 'reviews/all-reviews', }, 'attribute-filter': {}, + breadcrumbs: {}, cart: {}, 'catalog-sorting': {}, checkout: {}, diff --git a/plugins/woocommerce-blocks/src/BlockTypes/Breadcrumbs.php b/plugins/woocommerce-blocks/src/BlockTypes/Breadcrumbs.php new file mode 100644 index 00000000000..dc25d2258bd --- /dev/null +++ b/plugins/woocommerce-blocks/src/BlockTypes/Breadcrumbs.php @@ -0,0 +1,57 @@ +%4$s', + 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; + } +} diff --git a/plugins/woocommerce-blocks/src/BlockTypesController.php b/plugins/woocommerce-blocks/src/BlockTypesController.php index dadfc4ee512..ad4ea3f4ee6 100644 --- a/plugins/woocommerce-blocks/src/BlockTypesController.php +++ b/plugins/woocommerce-blocks/src/BlockTypesController.php @@ -168,6 +168,7 @@ final class BlockTypesController { 'AllProducts', 'AllReviews', 'AttributeFilter', + 'Breadcrumbs', 'CatalogSorting', 'ClassicTemplate', 'CustomerAccount', @@ -249,6 +250,7 @@ final class BlockTypesController { $block_types = array_diff( $block_types, [ + 'Breadcrumbs', 'CatalogSorting', 'ClassicTemplate', 'ProductResultsCount', diff --git a/plugins/woocommerce-blocks/tests/e2e/specs/backend/breadcrumbs.test.js b/plugins/woocommerce-blocks/tests/e2e/specs/backend/breadcrumbs.test.js new file mode 100644 index 00000000000..cddb6e1b1d8 --- /dev/null +++ b/plugins/woocommerce-blocks/tests/e2e/specs/backend/breadcrumbs.test.js @@ -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 ); + } ); + } ); +} );