`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:
parent
0f1634d6da
commit
40cde50879
|
@ -24,6 +24,14 @@ export const blockAttributes: BlockAttributes = {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
prefix: {
|
||||||
|
type: 'string',
|
||||||
|
default: 'SKU:',
|
||||||
|
},
|
||||||
|
suffix: {
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default blockAttributes;
|
export default blockAttributes;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import {
|
import {
|
||||||
useInnerBlockLayoutContext,
|
useInnerBlockLayoutContext,
|
||||||
|
@ -10,6 +9,8 @@ import {
|
||||||
import { withProductDataContext } from '@woocommerce/shared-hocs';
|
import { withProductDataContext } from '@woocommerce/shared-hocs';
|
||||||
import type { HTMLAttributes } from 'react';
|
import type { HTMLAttributes } from 'react';
|
||||||
import { useStyleProps } from '@woocommerce/base-hooks';
|
import { useStyleProps } from '@woocommerce/base-hooks';
|
||||||
|
import { RichText } from '@wordpress/block-editor';
|
||||||
|
import type { BlockEditProps } from '@wordpress/blocks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -17,18 +18,24 @@ import { useStyleProps } from '@woocommerce/base-hooks';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
import type { Attributes } from './types';
|
import type { Attributes } from './types';
|
||||||
|
|
||||||
type Props = Attributes & HTMLAttributes< HTMLDivElement >;
|
type Props = BlockEditProps< Attributes > & HTMLAttributes< HTMLDivElement >;
|
||||||
|
|
||||||
const Preview = ( {
|
const Preview = ( {
|
||||||
|
setAttributes,
|
||||||
parentClassName,
|
parentClassName,
|
||||||
sku,
|
sku,
|
||||||
className,
|
className,
|
||||||
style,
|
style,
|
||||||
|
prefix,
|
||||||
|
suffix,
|
||||||
}: {
|
}: {
|
||||||
|
setAttributes: ( attributes: Record< string, unknown > ) => void;
|
||||||
parentClassName: string;
|
parentClassName: string;
|
||||||
sku: string;
|
sku: string;
|
||||||
className?: string | undefined;
|
className?: string | undefined;
|
||||||
style?: React.CSSProperties | undefined;
|
style?: React.CSSProperties | undefined;
|
||||||
|
prefix?: string;
|
||||||
|
suffix?: string;
|
||||||
} ) => (
|
} ) => (
|
||||||
<div
|
<div
|
||||||
className={ clsx( className, {
|
className={ clsx( className, {
|
||||||
|
@ -36,7 +43,19 @@ const Preview = ( {
|
||||||
} ) }
|
} ) }
|
||||||
style={ style }
|
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>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -50,9 +69,12 @@ const Block = ( props: Props ): JSX.Element | null => {
|
||||||
if ( props.isDescendentOfSingleProductTemplate ) {
|
if ( props.isDescendentOfSingleProductTemplate ) {
|
||||||
return (
|
return (
|
||||||
<Preview
|
<Preview
|
||||||
|
setAttributes={ props.setAttributes }
|
||||||
parentClassName={ parentClassName }
|
parentClassName={ parentClassName }
|
||||||
className={ className }
|
className={ className }
|
||||||
sku={ 'Product SKU' }
|
sku={ 'Product SKU' }
|
||||||
|
prefix={ props.prefix }
|
||||||
|
suffix={ props.suffix }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -63,9 +85,12 @@ const Block = ( props: Props ): JSX.Element | null => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Preview
|
<Preview
|
||||||
|
setAttributes={ props.setAttributes }
|
||||||
className={ className }
|
className={ className }
|
||||||
parentClassName={ parentClassName }
|
parentClassName={ parentClassName }
|
||||||
sku={ sku }
|
sku={ sku }
|
||||||
|
prefix={ props.prefix }
|
||||||
|
suffix={ props.suffix }
|
||||||
{ ...( props.isDescendantOfAllProducts && {
|
{ ...( props.isDescendantOfAllProducts && {
|
||||||
className: clsx(
|
className: clsx(
|
||||||
className,
|
className,
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { useEffect } from '@wordpress/element';
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
*/
|
*/
|
||||||
|
import './editor.scss';
|
||||||
import Block from './block';
|
import Block from './block';
|
||||||
import type { Attributes } from './types';
|
import type { Attributes } from './types';
|
||||||
import { useIsDescendentOfSingleProductBlock } from '../shared/use-is-descendent-of-single-product-block';
|
import { useIsDescendentOfSingleProductBlock } from '../shared/use-is-descendent-of-single-product-block';
|
||||||
|
@ -68,7 +69,7 @@ const Edit = ( {
|
||||||
attributes.isDescendantOfAllProducts ? undefined : style
|
attributes.isDescendantOfAllProducts ? undefined : style
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Block { ...blockAttrs } />
|
<Block { ...blockAttrs } setAttributes={ setAttributes } />
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
.wc-block-components-product-sku strong {
|
||||||
|
margin-left: $gap-smallest;
|
||||||
|
margin-right: $gap-smallest;
|
||||||
|
}
|
|
@ -29,6 +29,9 @@ const blockConfig: BlockConfiguration = {
|
||||||
'woocommerce/product-meta',
|
'woocommerce/product-meta',
|
||||||
],
|
],
|
||||||
edit,
|
edit,
|
||||||
|
save() {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
supports,
|
supports,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
.wc-block-components-product-sku {
|
.wc-block-components-product-sku {
|
||||||
display: block;
|
display: block;
|
||||||
text-transform: uppercase;
|
|
||||||
@include font-size(small);
|
@include font-size(small);
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,6 @@ export interface Attributes {
|
||||||
isDescendentOfSingleProductBlock: boolean;
|
isDescendentOfSingleProductBlock: boolean;
|
||||||
showProductSelector: boolean;
|
showProductSelector: boolean;
|
||||||
isDescendantOfAllProducts: boolean;
|
isDescendantOfAllProducts: boolean;
|
||||||
|
prefix: string;
|
||||||
|
suffix: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: enhancement
|
||||||
|
|
||||||
|
Product SKU block: add editable prefixes and suffixes.
|
|
@ -69,14 +69,27 @@ class ProductSKU extends AbstractBlock {
|
||||||
|
|
||||||
$styles_and_classes = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes );
|
$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(
|
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">
|
'<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:
|
%3$s
|
||||||
<strong class="sku">%3$s</strong>
|
<strong class="sku">%4$s</strong>
|
||||||
|
%5$s
|
||||||
</div>',
|
</div>',
|
||||||
esc_attr( $styles_and_classes['classes'] ),
|
esc_attr( $styles_and_classes['classes'] ),
|
||||||
esc_attr( $styles_and_classes['styles'] ?? '' ),
|
esc_attr( $styles_and_classes['styles'] ?? '' ),
|
||||||
$product_sku
|
$prefix,
|
||||||
|
$product_sku,
|
||||||
|
$suffix
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue