`Product SKU` improvements (#51033)

* Add new prefix and suffix attributes

* Add editable prefix & suffix rich text fields

* Remove the uppercase style from prefix and suffix

* Render the prefix and suffix in the front end

* Fix lint errors

* Handle old sku block without prefix and suffix

* Improve the editor styles

* Add changefile(s) from automation for the following project(s): woocommerce-blocks, woocommerce

* Use wp_kses_post to filter and format the suffix and perfix

* Address extra space when empty and better escaping

---------

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Alba Rincón 2024-08-30 10:23:28 +02:00 committed by GitHub
parent 0f1634d6da
commit 40cde50879
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 71 additions and 8 deletions

View File

@ -24,6 +24,14 @@ export const blockAttributes: BlockAttributes = {
type: 'boolean',
default: false,
},
prefix: {
type: 'string',
default: 'SKU:',
},
suffix: {
type: 'string',
default: '',
},
};
export default blockAttributes;

View File

@ -1,7 +1,6 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import clsx from 'clsx';
import {
useInnerBlockLayoutContext,
@ -10,6 +9,8 @@ import {
import { withProductDataContext } from '@woocommerce/shared-hocs';
import type { HTMLAttributes } from 'react';
import { useStyleProps } from '@woocommerce/base-hooks';
import { RichText } from '@wordpress/block-editor';
import type { BlockEditProps } from '@wordpress/blocks';
/**
* Internal dependencies
@ -17,18 +18,24 @@ import { useStyleProps } from '@woocommerce/base-hooks';
import './style.scss';
import type { Attributes } from './types';
type Props = Attributes & HTMLAttributes< HTMLDivElement >;
type Props = BlockEditProps< Attributes > & HTMLAttributes< HTMLDivElement >;
const Preview = ( {
setAttributes,
parentClassName,
sku,
className,
style,
prefix,
suffix,
}: {
setAttributes: ( attributes: Record< string, unknown > ) => void;
parentClassName: string;
sku: string;
className?: string | undefined;
style?: React.CSSProperties | undefined;
prefix?: string;
suffix?: string;
} ) => (
<div
className={ clsx( className, {
@ -36,7 +43,19 @@ const Preview = ( {
} ) }
style={ style }
>
{ __( 'SKU:', 'woocommerce' ) } <strong>{ sku }</strong>
<RichText
tagName="span"
placeholder="Prefix"
value={ prefix }
onChange={ ( value ) => setAttributes( { prefix: value } ) }
/>
<strong>{ sku }</strong>
<RichText
tagName="span"
placeholder="Suffix"
value={ suffix }
onChange={ ( value ) => setAttributes( { suffix: value } ) }
/>
</div>
);
@ -50,9 +69,12 @@ const Block = ( props: Props ): JSX.Element | null => {
if ( props.isDescendentOfSingleProductTemplate ) {
return (
<Preview
setAttributes={ props.setAttributes }
parentClassName={ parentClassName }
className={ className }
sku={ 'Product SKU' }
prefix={ props.prefix }
suffix={ props.suffix }
/>
);
}
@ -63,9 +85,12 @@ const Block = ( props: Props ): JSX.Element | null => {
return (
<Preview
setAttributes={ props.setAttributes }
className={ className }
parentClassName={ parentClassName }
sku={ sku }
prefix={ props.prefix }
suffix={ props.suffix }
{ ...( props.isDescendantOfAllProducts && {
className: clsx(
className,

View File

@ -10,6 +10,7 @@ import { useEffect } from '@wordpress/element';
/**
* Internal dependencies
*/
import './editor.scss';
import Block from './block';
import type { Attributes } from './types';
import { useIsDescendentOfSingleProductBlock } from '../shared/use-is-descendent-of-single-product-block';
@ -68,7 +69,7 @@ const Edit = ( {
attributes.isDescendantOfAllProducts ? undefined : style
}
>
<Block { ...blockAttrs } />
<Block { ...blockAttrs } setAttributes={ setAttributes } />
</div>
</>
);

View File

@ -0,0 +1,4 @@
.wc-block-components-product-sku strong {
margin-left: $gap-smallest;
margin-right: $gap-smallest;
}

View File

@ -29,6 +29,9 @@ const blockConfig: BlockConfiguration = {
'woocommerce/product-meta',
],
edit,
save() {
return null;
},
supports,
};

View File

@ -1,6 +1,9 @@
.wc-block-components-product-sku {
display: block;
text-transform: uppercase;
@include font-size(small);
overflow-wrap: break-word;
strong {
text-transform: uppercase;
}
}

View File

@ -5,4 +5,6 @@ export interface Attributes {
isDescendentOfSingleProductBlock: boolean;
showProductSelector: boolean;
isDescendantOfAllProducts: boolean;
prefix: string;
suffix: string;
}

View File

@ -0,0 +1,4 @@
Significance: minor
Type: enhancement
Product SKU block: add editable prefixes and suffixes.

View File

@ -69,14 +69,27 @@ class ProductSKU extends AbstractBlock {
$styles_and_classes = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes );
$prefix = isset( $attributes['prefix'] ) ? wp_kses_post( ( $attributes['prefix'] ) ) : __( 'SKU: ', 'woocommerce' );
if ( ! empty( $prefix ) ) {
$prefix = sprintf( '<span class="prefix">%s</span>', $prefix );
}
$suffix = isset( $attributes['suffix'] ) ? wp_kses_post( ( $attributes['suffix'] ) ) : '';
if ( ! empty( $suffix ) ) {
$suffix = sprintf( '<span class="suffix">%s</span>', $suffix );
}
return sprintf(
'<div class="wc-block-components-product-sku wc-block-grid__product-sku wp-block-woocommerce-product-sku product_meta %1$s" style="%2$s">
SKU:
<strong class="sku">%3$s</strong>
%3$s
<strong class="sku">%4$s</strong>
%5$s
</div>',
esc_attr( $styles_and_classes['classes'] ),
esc_attr( $styles_and_classes['styles'] ?? '' ),
$product_sku
$prefix,
$product_sku,
$suffix
);
}
}