This repository has been archived by the owner on Feb 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 221
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Single Product Details block (#8225)
* Add minimum structure for Single Product Details block * Add tests for Single Product Details block * wip: create block structure and add initial styles * Add block details to the SingleProductDetails.php file * Render tabs title with empty content * Use woocommerce_output_product_data_tabs function to retrieve tabs data * Remove customizations for the Single Product Details block * Remove unnecessary console.log from the Edit.tsx file * Remove block classname from block wrapper * Remove unnecessary WooCommerce tabs filter from the BlockTemplatesController * Remove attributes property from the block registration * Remove isExperimental flag for the Single Product Details block * Remove get_classes_and_styles_by_attributes method from SingleProductDetails block * Prevent Single Product Details block from apppearing in Pages or Posts * Fix PHP Coding Standards warnings * update block name * fix SCSS linter error * move blocks into product-elements folder and rename to product-details * avoid 404 error * disable js asset enqueue --------- Co-authored-by: Luigi Teschio <gigitux@gmail.com>
- Loading branch information
1 parent
9ff32cc
commit 9095720
Showing
13 changed files
with
319 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
assets/js/atomic/blocks/product-elements/product-details/block.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "woocommerce/product-details", | ||
"version": "1.0.0", | ||
"icon": "info", | ||
"title": "Product Details", | ||
"description": "A block that allows your customers to see details and reviews about the product.", | ||
"category": "woocommerce", | ||
"keywords": [ "WooCommerce" ], | ||
"supports": {}, | ||
"attributes": {}, | ||
"textdomain": "woo-gutenberg-products-block", | ||
"apiVersion": 2, | ||
"$schema": "https://schemas.wp.org/trunk/block.json" | ||
} |
95 changes: 95 additions & 0 deletions
95
assets/js/atomic/blocks/product-elements/product-details/block.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import classnames from 'classnames'; | ||
import { __ } from '@wordpress/i18n'; | ||
import { useBlockProps } from '@wordpress/block-editor'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
|
||
interface SingleProductTab { | ||
id: string; | ||
title: string; | ||
active: boolean; | ||
content: string | undefined; | ||
} | ||
|
||
const ProductTabTitle = ( { | ||
id, | ||
title, | ||
active, | ||
}: Pick< SingleProductTab, 'id' | 'title' | 'active' > ) => { | ||
return ( | ||
<li | ||
className={ classnames( `${ id }_tab`, { | ||
active, | ||
} ) } | ||
id={ `tab-title-${ id }` } | ||
role="tab" | ||
aria-controls={ `tab-${ id }` } | ||
> | ||
<a href={ `#tab-${ id }` }>{ title }</a> | ||
</li> | ||
); | ||
}; | ||
|
||
const ProductTabContent = ( { | ||
id, | ||
content, | ||
}: Pick< SingleProductTab, 'id' | 'content' > ) => { | ||
return ( | ||
<div | ||
className={ `${ id }_tab` } | ||
id={ `tab-title-${ id }` } | ||
role="tab" | ||
aria-controls={ `tab-${ id }` } | ||
> | ||
{ content } | ||
</div> | ||
); | ||
}; | ||
|
||
export const SingleProductDetails = () => { | ||
const blockProps = useBlockProps(); | ||
const productTabs = [ | ||
{ | ||
id: 'description', | ||
title: 'Description', | ||
active: true, | ||
content: __( | ||
'This block lists description, attributes and reviews for a single product.', | ||
'woo-gutenberg-products-block' | ||
), | ||
}, | ||
{ | ||
id: 'additional_information', | ||
title: 'Additional Information', | ||
active: false, | ||
}, | ||
{ id: 'reviews', title: 'Reviews', active: false }, | ||
]; | ||
const tabsTitle = productTabs.map( ( { id, title, active } ) => ( | ||
<ProductTabTitle | ||
key={ id } | ||
id={ id } | ||
title={ title } | ||
active={ active } | ||
/> | ||
) ); | ||
const tabsContent = productTabs.map( ( { id, content } ) => ( | ||
<ProductTabContent key={ id } id={ id } content={ content } /> | ||
) ); | ||
|
||
return ( | ||
<div { ...blockProps }> | ||
<ul className="tabs" role="tablist"> | ||
{ tabsTitle } | ||
</ul> | ||
{ tabsContent } | ||
</div> | ||
); | ||
}; | ||
|
||
export default SingleProductDetails; |
31 changes: 31 additions & 0 deletions
31
assets/js/atomic/blocks/product-elements/product-details/edit.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { useBlockProps } from '@wordpress/block-editor'; | ||
import { Disabled } from '@wordpress/components'; | ||
import type { BlockEditProps } from '@wordpress/blocks'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import Block from './block'; | ||
import { Attributes } from './types'; | ||
|
||
const Edit = ( { attributes }: BlockEditProps< Attributes > ) => { | ||
const { className } = attributes; | ||
const blockProps = useBlockProps( { | ||
className, | ||
} ); | ||
|
||
return ( | ||
<> | ||
<div { ...blockProps }> | ||
<Disabled> | ||
<Block /> | ||
</Disabled> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default Edit; |
24 changes: 24 additions & 0 deletions
24
assets/js/atomic/blocks/product-elements/product-details/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { registerBlockSingleProductTemplate } from '@woocommerce/atomic-utils'; | ||
import { registerBlockType, unregisterBlockType } from '@wordpress/blocks'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import metadata from './block.json'; | ||
import edit from './edit'; | ||
|
||
registerBlockSingleProductTemplate( { | ||
registerBlockFn: () => { | ||
// @ts-expect-error: `registerBlockType` is a function that is typed in WordPress core. | ||
registerBlockType( metadata, { | ||
edit, | ||
} ); | ||
}, | ||
unregisterBlockFn: () => { | ||
unregisterBlockType( metadata.name ); | ||
}, | ||
blockName: metadata.name, | ||
} ); |
46 changes: 46 additions & 0 deletions
46
assets/js/atomic/blocks/product-elements/product-details/style.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
.wp-block-woocommerce-product-details { | ||
ul.tabs { | ||
list-style: none; | ||
padding: 0 0 0 1em; | ||
margin: 0 0 1.618em; | ||
overflow: hidden; | ||
position: relative; | ||
border-bottom: 1px solid $gray-200; | ||
|
||
li { | ||
border: 1px solid $gray-200; | ||
background-color: $white; | ||
display: inline-block; | ||
position: relative; | ||
z-index: 0; | ||
border-radius: 4px 4px 0 0; | ||
margin: 0; | ||
padding: 0.5em 1em; | ||
opacity: 0.5; | ||
|
||
a { | ||
display: inline-block; | ||
font-weight: 700; | ||
color: $black; | ||
text-decoration: none; | ||
|
||
&:hover { | ||
text-decoration: none; | ||
color: color.adjust($black, $lightness: 10%); | ||
} | ||
} | ||
|
||
&.active { | ||
background: $gray-100; | ||
z-index: 2; | ||
border-bottom-color: $gray-200; | ||
opacity: 1; | ||
|
||
a { | ||
color: inherit; | ||
text-shadow: inherit; | ||
} | ||
} | ||
} | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
assets/js/atomic/blocks/product-elements/product-details/types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export interface Attributes { | ||
className?: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<?php | ||
|
||
namespace Automattic\WooCommerce\Blocks\BlockTypes; | ||
|
||
/** | ||
* ProductDetails class. | ||
*/ | ||
class ProductDetails extends AbstractBlock { | ||
/** | ||
* Block name. | ||
* | ||
* @var string | ||
*/ | ||
protected $block_name = 'product-details'; | ||
|
||
/** | ||
* It isn't necessary register block assets because it is a server side block. | ||
*/ | ||
protected function register_block_type_assets() { | ||
return null; | ||
} | ||
|
||
/** | ||
* Render the block. | ||
* | ||
* @param array $attributes Block attributes. | ||
* @param string $content Block content. | ||
* @param WP_Block $block Block instance. | ||
* | ||
* @return string Rendered block output. | ||
*/ | ||
protected function render( $attributes, $content, $block ) { | ||
$tabs = $this->render_tabs(); | ||
|
||
$classname = $attributes['className'] ?? ''; | ||
|
||
return sprintf( | ||
'<div class="wp-block-woocommerce-product-details %1$s"> | ||
%2$s | ||
</div>', | ||
esc_attr( $classname ), | ||
$tabs | ||
); | ||
} | ||
|
||
/** | ||
* Gets the tabs with their content to be rendered by the block. | ||
* | ||
* @return string The tabs html to be rendered by the block | ||
*/ | ||
protected function render_tabs() { | ||
ob_start(); | ||
|
||
while ( have_posts() ) { | ||
the_post(); | ||
woocommerce_output_product_data_tabs(); | ||
} | ||
|
||
$tabs = ob_get_clean(); | ||
|
||
return $tabs; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
tests/e2e/config/custom-matchers/__fixtures__/single-product-details.fixture.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"title":"Product Details Block","pageContent":"<!-- wp:woocommerce/single-product-details /-->"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { getAllBlocks, switchUserToAdmin } from '@wordpress/e2e-test-utils'; | ||
import { visitBlockPage } from '@woocommerce/blocks-test-utils'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { insertBlockDontWaitForInsertClose } from '../../utils.js'; | ||
|
||
const block = { | ||
name: 'Product Details', | ||
slug: 'woocommerce/single-product-details', | ||
class: '.wc-block-single-product-details', | ||
}; | ||
|
||
describe( `${ block.name } Block`, () => { | ||
beforeAll( async () => { | ||
await switchUserToAdmin(); | ||
await visitBlockPage( `${ block.name } Block` ); | ||
} ); | ||
|
||
it( 'can be inserted more than once', async () => { | ||
await insertBlockDontWaitForInsertClose( block.name ); | ||
expect( await getAllBlocks() ).toHaveLength( 2 ); | ||
} ); | ||
|
||
it( 'renders without crashing', async () => { | ||
await expect( page ).toRenderBlock( block ); | ||
} ); | ||
} ); |