diff --git a/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/block.json b/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/block.json index 6e8df5f272d..633c831d1c6 100644 --- a/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/block.json +++ b/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/block.json @@ -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" ], diff --git a/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/block.tsx b/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/block.tsx index a011fb84da8..169f7c7cab1 100644 --- a/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/block.tsx +++ b/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/block.tsx @@ -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 && ( +

{ __( 'Description', 'woocommerce' ) }

+ ) } +

+ { __( + 'This block lists description, attributes and reviews for a single product.', + 'woocommerce' + ) } +

+ ), }, { diff --git a/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/edit.tsx b/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/edit.tsx index 471f9f7e30b..d4d652c3ee2 100644 --- a/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/edit.tsx +++ b/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/edit.tsx @@ -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 ( <>
+ + + + setAttributes( { + hideTabTitle: ! hideTabTitle, + } ) + } + /> + + - +
diff --git a/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/types.ts b/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/types.ts index aa9b37b316a..36a5d5b5d58 100644 --- a/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/types.ts +++ b/plugins/woocommerce-blocks/assets/js/atomic/blocks/product-elements/product-details/types.ts @@ -1,3 +1,4 @@ export interface Attributes { className?: string; + hideTabTitle?: boolean; } diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/single-product-details/single-product-details.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/single-product-details/single-product-details.block_theme.spec.ts index 967ddf62d00..9e45c19be36 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/single-product-details/single-product-details.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/single-product-details/single-product-details.block_theme.spec.ts @@ -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(); + } ); } ); diff --git a/plugins/woocommerce/changelog/add-47895-show-tab-title-attribute-product-details b/plugins/woocommerce/changelog/add-47895-show-tab-title-attribute-product-details new file mode 100644 index 00000000000..9b974a1f1cf --- /dev/null +++ b/plugins/woocommerce/changelog/add-47895-show-tab-title-attribute-product-details @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Add 'Show tab title' attribute to the Product Details block diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/ProductDetails.php b/plugins/woocommerce/src/Blocks/BlockTypes/ProductDetails.php index c512966d6ad..907d198dde9 100644 --- a/plugins/woocommerce/src/Blocks/BlockTypes/ProductDetails.php +++ b/plugins/woocommerce/src/Blocks/BlockTypes/ProductDetails.php @@ -1,6 +1,7 @@ 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 );