Use WooCommerce thumbnail images in Blocks (https://github.com/woocommerce/woocommerce-blocks/pull/2755)
* Remove legacy files * Use thumbnail product image for Cart, Checkout and Reviews blocks * Add option to toggle between full size and cropped image to the Atomic Product image block
This commit is contained in:
parent
b40600a8b2
commit
3fae904643
|
@ -11,6 +11,10 @@ export const blockAttributes = {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
default: 'right',
|
default: 'right',
|
||||||
},
|
},
|
||||||
|
imageSizing: {
|
||||||
|
type: 'string',
|
||||||
|
default: 'full-size',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default blockAttributes;
|
export default blockAttributes;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import './style.scss';
|
||||||
*/
|
*/
|
||||||
const Block = ( {
|
const Block = ( {
|
||||||
className,
|
className,
|
||||||
|
imageSizing = 'full-size',
|
||||||
productLink = true,
|
productLink = true,
|
||||||
showSaleBadge,
|
showSaleBadge,
|
||||||
saleBadgeAlign = 'right',
|
saleBadgeAlign = 'right',
|
||||||
|
@ -78,6 +79,7 @@ const Block = ( {
|
||||||
image={ image }
|
image={ image }
|
||||||
onLoad={ () => setImageLoaded( true ) }
|
onLoad={ () => setImageLoaded( true ) }
|
||||||
loaded={ imageLoaded }
|
loaded={ imageLoaded }
|
||||||
|
showFullSize={ imageSizing !== 'cropped' }
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
) : (
|
) : (
|
||||||
|
@ -92,6 +94,7 @@ const Block = ( {
|
||||||
image={ image }
|
image={ image }
|
||||||
onLoad={ () => setImageLoaded( true ) }
|
onLoad={ () => setImageLoaded( true ) }
|
||||||
loaded={ imageLoaded }
|
loaded={ imageLoaded }
|
||||||
|
showFullSize={ imageSizing !== 'cropped' }
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
) }
|
) }
|
||||||
|
@ -103,19 +106,28 @@ const ImagePlaceholder = () => {
|
||||||
return <img src={ PLACEHOLDER_IMG_SRC } alt="" />;
|
return <img src={ PLACEHOLDER_IMG_SRC } alt="" />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Image = ( { image, onLoad, loaded } ) => {
|
const Image = ( { image, onLoad, loaded, showFullSize } ) => {
|
||||||
const { thumbnail, srcset, sizes, alt } = image || {};
|
const { thumbnail, src, srcset, sizes, alt } = image || {};
|
||||||
|
|
||||||
|
let imageProps = {
|
||||||
|
alt,
|
||||||
|
onLoad,
|
||||||
|
hidden: ! loaded,
|
||||||
|
src: thumbnail,
|
||||||
|
};
|
||||||
|
if ( showFullSize ) {
|
||||||
|
imageProps = {
|
||||||
|
...imageProps,
|
||||||
|
src,
|
||||||
|
srcSet: srcset,
|
||||||
|
sizes,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<img
|
{ /* eslint-disable-next-line jsx-a11y/alt-text */ }
|
||||||
src={ thumbnail }
|
<img { ...imageProps } />
|
||||||
srcSet={ srcset }
|
|
||||||
sizes={ sizes }
|
|
||||||
alt={ alt }
|
|
||||||
onLoad={ onLoad }
|
|
||||||
hidden={ ! loaded }
|
|
||||||
/>
|
|
||||||
{ ! loaded && <ImagePlaceholder /> }
|
{ ! loaded && <ImagePlaceholder /> }
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { Disabled, PanelBody, ToggleControl } from '@wordpress/components';
|
import { Disabled, PanelBody, ToggleControl } from '@wordpress/components';
|
||||||
import { InspectorControls } from '@wordpress/block-editor';
|
import { InspectorControls } from '@wordpress/block-editor';
|
||||||
|
import { __experimentalCreateInterpolateElement } from 'wordpress-element';
|
||||||
import ToggleButtonControl from '@woocommerce/block-components/toggle-button-control';
|
import ToggleButtonControl from '@woocommerce/block-components/toggle-button-control';
|
||||||
|
import { getAdminLink } from '@woocommerce/settings';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -12,7 +14,12 @@ import ToggleButtonControl from '@woocommerce/block-components/toggle-button-con
|
||||||
import Block from './block';
|
import Block from './block';
|
||||||
|
|
||||||
export default ( { attributes, setAttributes } ) => {
|
export default ( { attributes, setAttributes } ) => {
|
||||||
const { productLink, showSaleBadge, saleBadgeAlign } = attributes;
|
const {
|
||||||
|
productLink,
|
||||||
|
imageSizing,
|
||||||
|
showSaleBadge,
|
||||||
|
saleBadgeAlign,
|
||||||
|
} = attributes;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -87,6 +94,50 @@ export default ( { attributes, setAttributes } ) => {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
) }
|
) }
|
||||||
|
<ToggleButtonControl
|
||||||
|
label={ __(
|
||||||
|
'Image Sizing',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
) }
|
||||||
|
help={ __experimentalCreateInterpolateElement(
|
||||||
|
__(
|
||||||
|
'Product image cropping can be modified in the <a>Customizer</a>.',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
),
|
||||||
|
{
|
||||||
|
a: (
|
||||||
|
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||||
|
<a
|
||||||
|
href={ `${ getAdminLink(
|
||||||
|
'customize.php'
|
||||||
|
) }?autofocus[panel]=woocommerce&autofocus[section]=woocommerce_product_images` }
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}
|
||||||
|
) }
|
||||||
|
value={ imageSizing }
|
||||||
|
options={ [
|
||||||
|
{
|
||||||
|
label: __(
|
||||||
|
'Full Size',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
),
|
||||||
|
value: 'full-size',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __(
|
||||||
|
'Cropped',
|
||||||
|
'woo-gutenberg-products-block'
|
||||||
|
),
|
||||||
|
value: 'cropped',
|
||||||
|
},
|
||||||
|
] }
|
||||||
|
onChange={ ( value ) =>
|
||||||
|
setAttributes( { imageSizing: value } )
|
||||||
|
}
|
||||||
|
/>
|
||||||
</PanelBody>
|
</PanelBody>
|
||||||
</InspectorControls>
|
</InspectorControls>
|
||||||
<Disabled>
|
<Disabled>
|
||||||
|
|
|
@ -10,10 +10,8 @@ import PropTypes from 'prop-types';
|
||||||
*/
|
*/
|
||||||
const ProductImage = ( { image = {} } ) => {
|
const ProductImage = ( { image = {} } ) => {
|
||||||
const imageProps = {
|
const imageProps = {
|
||||||
src: image.src || PLACEHOLDER_IMG_SRC,
|
src: image.thumbnail || PLACEHOLDER_IMG_SRC,
|
||||||
alt: decodeEntities( image.alt ) || '',
|
alt: decodeEntities( image.alt ) || '',
|
||||||
srcSet: image.srcset || '',
|
|
||||||
sizes: image.sizes || '',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return <img { ...imageProps } alt={ imageProps.alt } />;
|
return <img { ...imageProps } alt={ imageProps.alt } />;
|
||||||
|
@ -22,9 +20,7 @@ const ProductImage = ( { image = {} } ) => {
|
||||||
ProductImage.propTypes = {
|
ProductImage.propTypes = {
|
||||||
image: PropTypes.shape( {
|
image: PropTypes.shape( {
|
||||||
alt: PropTypes.string,
|
alt: PropTypes.string,
|
||||||
src: PropTypes.string,
|
thumbnail: PropTypes.string,
|
||||||
srcsizes: PropTypes.string,
|
|
||||||
srcset: PropTypes.string,
|
|
||||||
} ),
|
} ),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,7 @@ function getReviewImage( review, imageType, isLoading ) {
|
||||||
<img
|
<img
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
alt={ review.product_image?.alt || '' }
|
alt={ review.product_image?.alt || '' }
|
||||||
src={ review.product_image?.src || '' }
|
src={ review.product_image?.thumbnail || '' }
|
||||||
className="wc-block-review-list-item__image wc-block-components-review-list-item__image"
|
|
||||||
width="48"
|
|
||||||
height="48"
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<img
|
<img
|
||||||
|
@ -39,9 +36,6 @@ function getReviewImage( review, imageType, isLoading ) {
|
||||||
alt=""
|
alt=""
|
||||||
src={ review.reviewer_avatar_urls[ '48' ] || '' }
|
src={ review.reviewer_avatar_urls[ '48' ] || '' }
|
||||||
srcSet={ review.reviewer_avatar_urls[ '96' ] + ' 2x' }
|
srcSet={ review.reviewer_avatar_urls[ '96' ] + ' 2x' }
|
||||||
className="wc-block-review-list-item__image wc-block-components-review-list-item__image"
|
|
||||||
width="48"
|
|
||||||
height="48"
|
|
||||||
/>
|
/>
|
||||||
) }
|
) }
|
||||||
{ review.verified && (
|
{ review.verified && (
|
||||||
|
|
|
@ -67,16 +67,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.wc-block-components-review-list-item__image {
|
.wc-block-components-review-list-item__image {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
grid-row: 1 / 3;
|
grid-row: 1 / 3;
|
||||||
width: 48px;
|
justify-content: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
width: 48px;
|
||||||
|
|
||||||
img {
|
> img {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: block;
|
display: block;
|
||||||
|
height: auto;
|
||||||
|
max-height: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
width: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { decodeEntities } from '@wordpress/html-entities';
|
|
||||||
import { PLACEHOLDER_IMG_SRC } from '@woocommerce/block-settings';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats and returns an image element.
|
|
||||||
*/
|
|
||||||
const ProductImage = ( { image = {} } ) => {
|
|
||||||
const imageProps = {
|
|
||||||
src: image.src || PLACEHOLDER_IMG_SRC,
|
|
||||||
alt: decodeEntities( image.alt ) || '',
|
|
||||||
srcSet: image.srcset || '',
|
|
||||||
sizes: image.sizes || '',
|
|
||||||
};
|
|
||||||
|
|
||||||
return <img { ...imageProps } alt={ imageProps.alt } />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProductImage;
|
|
|
@ -1,25 +0,0 @@
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { __, sprintf } from '@wordpress/i18n';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a low stock badge for a line item.
|
|
||||||
*/
|
|
||||||
const ProductLowStockBadge = ( { lowStockRemaining } ) => {
|
|
||||||
if ( ! lowStockRemaining ) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="wc-block-cart-item__low-stock-badge">
|
|
||||||
{ sprintf(
|
|
||||||
/* translators: %s stock amount (number of items in stock for product) */
|
|
||||||
__( '%s left in stock', 'woo-gutenberg-products-block' ),
|
|
||||||
lowStockRemaining
|
|
||||||
) }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProductLowStockBadge;
|
|
|
@ -1,29 +0,0 @@
|
||||||
/**
|
|
||||||
* External dependencies
|
|
||||||
*/
|
|
||||||
import { decodeEntities } from '@wordpress/html-entities';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a formatted element containing variation details.
|
|
||||||
*/
|
|
||||||
const ProductVariationData = ( { variation } ) => {
|
|
||||||
const variationsText = variation
|
|
||||||
.map( ( v ) => {
|
|
||||||
if ( v.attribute ) {
|
|
||||||
return `${ decodeEntities( v.attribute ) }: ${ decodeEntities(
|
|
||||||
v.value
|
|
||||||
) }`;
|
|
||||||
}
|
|
||||||
// Support for product attributes with no name/key
|
|
||||||
return `${ decodeEntities( v.value ) }`;
|
|
||||||
} )
|
|
||||||
.join( ' / ' );
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="wc-block-cart-item__product-attributes">
|
|
||||||
{ variationsText }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProductVariationData;
|
|
Loading…
Reference in New Issue