Add 'Show tab title' attribute to the Product Details block (#50884)

* Add 'Show tab title' attribute to the Product Details block

* Add tests

* Add changelog file

* Linting

* Use editor.selectBlocks() instead of block.click()
This commit is contained in:
Albert Juhé Lluveras 2024-08-27 15:10:49 +02:00 committed by GitHub
parent f2941d76e5
commit 1e650d06a9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 130 additions and 10 deletions

View File

@ -5,6 +5,12 @@
"title": "Product Details",
"description": "Display a product's description, attributes, and reviews.",
"category": "woocommerce-product-elements",
"attributes": {
"hideTabTitle": {
"type": "boolean",
"default": false
}
},
"keywords": [
"WooCommerce"
],

View File

@ -8,7 +8,7 @@ interface SingleProductTab {
id: string;
title: string;
active: boolean;
content: string | undefined;
content: React.JSX.Element | undefined;
}
const ProductTabTitle = ( {
@ -46,15 +46,28 @@ const ProductTabContent = ( {
);
};
export const SingleProductDetails = () => {
export const SingleProductDetails = ( {
hideTabTitle,
}: {
hideTabTitle: boolean;
} ) => {
const productTabs = [
{
id: 'description',
title: 'Description',
active: true,
content: __(
'This block lists description, attributes and reviews for a single product.',
'woocommerce'
content: (
<>
{ ! hideTabTitle && (
<h2>{ __( 'Description', 'woocommerce' ) }</h2>
) }
<p>
{ __(
'This block lists description, attributes and reviews for a single product.',
'woocommerce'
) }
</p>
</>
),
},
{

View File

@ -1,9 +1,10 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import { Disabled } from '@wordpress/components';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { Disabled, PanelBody, ToggleControl } from '@wordpress/components';
import type { BlockEditProps } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
@ -12,8 +13,11 @@ import Block from './block';
import { Attributes } from './types';
import './editor.scss';
const Edit = ( { attributes }: BlockEditProps< Attributes > ) => {
const { className } = attributes;
const Edit = ( {
attributes,
setAttributes,
}: BlockEditProps< Attributes > ) => {
const { className, hideTabTitle } = attributes;
const blockProps = useBlockProps( {
className,
} );
@ -21,8 +25,24 @@ const Edit = ( { attributes }: BlockEditProps< Attributes > ) => {
return (
<>
<div { ...blockProps }>
<InspectorControls key="inspector">
<PanelBody title={ __( 'Settings', 'woocommerce' ) }>
<ToggleControl
label={ __(
'Show tab title in content',
'woocommerce'
) }
checked={ ! hideTabTitle }
onChange={ () =>
setAttributes( {
hideTabTitle: ! hideTabTitle,
} )
}
/>
</PanelBody>
</InspectorControls>
<Disabled>
<Block />
<Block hideTabTitle={ hideTabTitle } />
</Disabled>
</div>
</>

View File

@ -1,3 +1,4 @@
export interface Attributes {
className?: string;
hideTabTitle?: boolean;
}

View File

@ -55,4 +55,56 @@ test.describe( `${ blockData.slug } Block`, () => {
/This block lists description, attributes and reviews for a single product./
);
} );
test( 'block hides tab title in content when toggle is off', async ( {
admin,
requestUtils,
editor,
page,
frontendUtils,
} ) => {
const template = await requestUtils.createTemplate( 'wp_template', {
slug: 'single-product-v-neck-t-shirt',
title: 'Product Details Test',
content: '',
} );
await admin.visitSiteEditor( {
postId: template.id,
postType: 'wp_template',
canvas: 'edit',
} );
await editor.insertBlock( {
name: blockData.slug,
} );
const block = await editor.getBlockByName( blockData.slug );
await editor.selectBlocks( block );
// Verify the "Description" h2 heading is visible by default.
await expect(
editor.canvas.locator( 'h2:has-text("Description")' )
).toBeVisible();
await editor.openDocumentSettingsSidebar();
await page.getByText( 'Show tab title in content' ).click();
// Verify the "Description" h2 heading has been hidden from the canvas.
await expect(
editor.canvas.locator( 'h2:has-text("Description")' )
).toBeHidden();
await editor.saveSiteEditorEntities( {
isOnlyCurrentEntityDirty: true,
} );
await frontendUtils.goToShop();
await page.getByText( 'V-Neck T-Shirt' ).click();
// Verify the "Description" h2 heading is not in the page.
await expect(
page.locator( 'h2:has-text("Description")' )
).toBeHidden();
} );
} );

View File

@ -0,0 +1,4 @@
Significance: minor
Type: enhancement
Add 'Show tab title' attribute to the Product Details block

View File

@ -1,6 +1,7 @@
<?php
namespace Automattic\WooCommerce\Blocks\BlockTypes;
use WP_HTML_Tag_Processor;
use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils;
/**
@ -50,8 +51,31 @@ class ProductDetails extends AbstractBlock {
* @return string Rendered block output.
*/
protected function render( $attributes, $content, $block ) {
$hide_tab_title = isset( $attributes['hideTabTitle'] ) ? $attributes['hideTabTitle'] : false;
if ( $hide_tab_title ) {
add_filter( 'woocommerce_product_description_heading', '__return_empty_string' );
add_filter( 'woocommerce_product_additional_information_heading', '__return_empty_string' );
add_filter( 'woocommerce_reviews_title', '__return_empty_string' );
}
$tabs = $this->render_tabs();
if ( $hide_tab_title ) {
remove_filter( 'woocommerce_product_description_heading', '__return_empty_string' );
remove_filter( 'woocommerce_product_additional_information_heading', '__return_empty_string' );
remove_filter( 'woocommerce_reviews_title', '__return_empty_string' );
// Remove the first `h2` of every `.wc-tab`. This is required for the Reviews tabs when there are no reviews and for plugin tabs.
$tabs_html = new WP_HTML_Tag_Processor( $tabs );
while ( $tabs_html->next_tag( array( 'class_name' => 'wc-tab' ) ) ) {
if ( $tabs_html->next_tag( 'h2' ) ) {
$tabs_html->set_attribute( 'hidden', 'true' );
}
}
$tabs = $tabs_html->get_updated_html();
}
$classname = $attributes['className'] ?? '';
$classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes );