Implement `Fixed image` and `Repeated image` media controls for the `Featured Product` (https://github.com/woocommerce/woocommerce-blocks/pull/6344)
* Add `Fixed` and `Repeated` background controls to `Featured Product` * Add `Repeated background` feature when the toggle is activated * Extract `get_image_url` function * Add the styles for rendering the repeated image on the frontend * Add `hasParallax` and `isRepeated` to the `block.json` file * Adjust styles * Remove unused function, improve phpdoc * Use alt and product name Fix error rebasing master * Hide alt if isRepeat is true When isRepeated is true, the image is a background so it does not make sense to have an alt attribute. * Add `Fixed image` behaviour * Remove unnecessary single quotes * Remove duplicated const due to rebasing * Fix focal point getting lost after enabling Fixed bg * Fix duotone for fixed and repeated images * Fix duotone for fixed and repeated images on the front end * Don't allow alt if the image is a bg not an img element
This commit is contained in:
parent
89a553a8a7
commit
22e6394d47
|
@ -52,9 +52,9 @@ import {
|
|||
dimRatioToClass,
|
||||
getCategoryImageId,
|
||||
getCategoryImageSrc,
|
||||
calculateBackgroundImagePosition,
|
||||
} from './utils';
|
||||
import { withCategory } from '../../hocs';
|
||||
import { calculateBackgroundImagePosition } from '../featured-product/utils';
|
||||
import { ConstrainedResizable } from '../featured-product/block';
|
||||
|
||||
const DEFAULT_EDITOR_SIZE = {
|
||||
|
|
|
@ -60,3 +60,14 @@ export {
|
|||
getBackgroundImageStyles,
|
||||
dimRatioToClass,
|
||||
};
|
||||
|
||||
export function calculateBackgroundImagePosition( coords ) {
|
||||
if ( ! coords ) return {};
|
||||
|
||||
const x = Math.round( coords.x * 100 );
|
||||
const y = Math.round( coords.y * 100 );
|
||||
|
||||
return {
|
||||
objectPosition: `${ x }% ${ y }%`,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -50,7 +50,11 @@ import { crop, Icon, starEmpty } from '@wordpress/icons';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { calculateBackgroundImagePosition, dimRatioToClass } from './utils';
|
||||
import {
|
||||
backgroundImageStyles,
|
||||
calculateImagePosition,
|
||||
dimRatioToClass,
|
||||
} from './utils';
|
||||
import {
|
||||
getImageSrcFromProduct,
|
||||
getImageIdFromProduct,
|
||||
|
@ -265,11 +269,17 @@ const FeaturedProduct = ( {
|
|||
|
||||
const getInspectorControls = () => {
|
||||
const url = attributes.mediaSrc || getImageSrcFromProduct( product );
|
||||
const { focalPoint = { x: 0.5, y: 0.5 } } = attributes;
|
||||
const {
|
||||
focalPoint = { x: 0.5, y: 0.5 },
|
||||
hasParallax,
|
||||
isRepeated,
|
||||
} = attributes;
|
||||
// FocalPointPicker was introduced in Gutenberg 5.0 (WordPress 5.2),
|
||||
// so we need to check if it exists before using it.
|
||||
const focalPointPickerExists = typeof FocalPointPicker === 'function';
|
||||
|
||||
const isImgElement = ! isRepeated && ! hasParallax;
|
||||
|
||||
return (
|
||||
<>
|
||||
<InspectorControls key="inspector">
|
||||
|
@ -313,50 +323,76 @@ const FeaturedProduct = ( {
|
|||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
>
|
||||
<ToggleGroupControl
|
||||
help={
|
||||
<>
|
||||
<p>
|
||||
{ __(
|
||||
'Choose “Cover” if you want the image to scale automatically to always fit its container.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</p>
|
||||
<p>
|
||||
{ __(
|
||||
'Note: by choosing “Cover” you will lose the ability to freely move the focal point precisely.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
<ToggleControl
|
||||
label={ __(
|
||||
'Image fit',
|
||||
'Fixed background',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
value={ attributes.imageFit }
|
||||
onChange={ ( value ) =>
|
||||
checked={ hasParallax }
|
||||
onChange={ () => {
|
||||
setAttributes( {
|
||||
imageFit: value,
|
||||
} )
|
||||
}
|
||||
>
|
||||
<ToggleGroupControlOption
|
||||
hasParallax: ! hasParallax,
|
||||
} );
|
||||
} }
|
||||
/>
|
||||
<ToggleControl
|
||||
label={ __(
|
||||
'Repeated background',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
checked={ isRepeated }
|
||||
onChange={ () => {
|
||||
setAttributes( {
|
||||
isRepeated: ! isRepeated,
|
||||
} );
|
||||
} }
|
||||
/>
|
||||
{ ! isRepeated && (
|
||||
<ToggleGroupControl
|
||||
help={
|
||||
<>
|
||||
<p>
|
||||
{ __(
|
||||
'Choose “Cover” if you want the image to scale automatically to always fit its container.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</p>
|
||||
<p>
|
||||
{ __(
|
||||
'Note: by choosing “Cover” you will lose the ability to freely move the focal point precisely.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
label={ __(
|
||||
'None',
|
||||
'Image fit',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
value="none"
|
||||
/>
|
||||
<ToggleGroupControlOption
|
||||
/* translators: "Cover" is a verb that indicates an image covering the entire container. */
|
||||
label={ __(
|
||||
'Cover',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
value="cover"
|
||||
/>
|
||||
</ToggleGroupControl>
|
||||
value={ attributes.imageFit }
|
||||
onChange={ ( value ) =>
|
||||
setAttributes( {
|
||||
imageFit: value,
|
||||
} )
|
||||
}
|
||||
>
|
||||
<ToggleGroupControlOption
|
||||
label={ __(
|
||||
'None',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
value="none"
|
||||
/>
|
||||
<ToggleGroupControlOption
|
||||
/* translators: "Cover" is a verb that indicates an image covering the entire container. */
|
||||
label={ __(
|
||||
'Cover',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
value="cover"
|
||||
/>
|
||||
</ToggleGroupControl>
|
||||
) }
|
||||
<FocalPointPicker
|
||||
label={ __(
|
||||
'Focal Point Picker',
|
||||
|
@ -370,30 +406,32 @@ const FeaturedProduct = ( {
|
|||
} )
|
||||
}
|
||||
/>
|
||||
<TextareaControl
|
||||
label={ __(
|
||||
'Alt text (alternative text)',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
value={ attributes.alt }
|
||||
onChange={ ( alt ) => {
|
||||
setAttributes( { alt } );
|
||||
} }
|
||||
help={
|
||||
<>
|
||||
<ExternalLink href="https://www.w3.org/WAI/tutorials/images/decision-tree">
|
||||
{ isImgElement && (
|
||||
<TextareaControl
|
||||
label={ __(
|
||||
'Alt text (alternative text)',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
value={ attributes.alt }
|
||||
onChange={ ( alt ) => {
|
||||
setAttributes( { alt } );
|
||||
} }
|
||||
help={
|
||||
<>
|
||||
<ExternalLink href="https://www.w3.org/WAI/tutorials/images/decision-tree">
|
||||
{ __(
|
||||
'Describe the purpose of the image',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</ExternalLink>
|
||||
{ __(
|
||||
'Describe the purpose of the image',
|
||||
'Leaving it empty will use the product name.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</ExternalLink>
|
||||
{ __(
|
||||
'Leaving it empty will use the product name.',
|
||||
'woo-gutenberg-products-block'
|
||||
) }
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
) }
|
||||
</PanelBody>
|
||||
) }
|
||||
<PanelColorGradientSettings
|
||||
|
@ -454,6 +492,8 @@ const FeaturedProduct = ( {
|
|||
contentAlign,
|
||||
dimRatio,
|
||||
focalPoint,
|
||||
hasParallax,
|
||||
isRepeated,
|
||||
imageFit,
|
||||
minHeight,
|
||||
overlayColor,
|
||||
|
@ -471,6 +511,7 @@ const FeaturedProduct = ( {
|
|||
'is-loading': ! product && isLoading,
|
||||
'is-not-found': ! product && ! isLoading,
|
||||
'has-background-dim': dimRatio !== 0,
|
||||
'is-repeated': isRepeated,
|
||||
},
|
||||
contentAlign !== 'center' && `has-${ contentAlign }-content`
|
||||
);
|
||||
|
@ -479,14 +520,31 @@ const FeaturedProduct = ( {
|
|||
borderRadius: style?.border?.radius,
|
||||
};
|
||||
|
||||
const backgroundImageStyle = {
|
||||
objectPosition: calculateImagePosition( focalPoint ),
|
||||
objectFit: imageFit,
|
||||
};
|
||||
|
||||
const isImgElement = ! isRepeated && ! hasParallax;
|
||||
|
||||
const wrapperStyle = {
|
||||
...getSpacingClassesAndStyles( attributes ).style,
|
||||
minHeight,
|
||||
};
|
||||
|
||||
const backgroundImageStyle = {
|
||||
...calculateBackgroundImagePosition( focalPoint ),
|
||||
objectFit: imageFit,
|
||||
const backgroundDivStyle = {
|
||||
...( ! isImgElement
|
||||
? {
|
||||
...backgroundImageStyles( backgroundImageSrc ),
|
||||
backgroundPosition: calculateImagePosition(
|
||||
focalPoint
|
||||
),
|
||||
}
|
||||
: undefined ),
|
||||
...( ! isRepeated && {
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundSize: imageFit === 'cover' ? imageFit : 'auto',
|
||||
} ),
|
||||
};
|
||||
|
||||
const overlayStyle = {
|
||||
|
@ -504,25 +562,40 @@ const FeaturedProduct = ( {
|
|||
/>
|
||||
<div className={ classes } style={ containerStyle }>
|
||||
<div
|
||||
className="wc-block-featured-product__wrapper"
|
||||
className={ classnames(
|
||||
'wc-block-featured-product__wrapper'
|
||||
) }
|
||||
style={ wrapperStyle }
|
||||
>
|
||||
<div
|
||||
className="wc-block-featured-product__overlay"
|
||||
style={ overlayStyle }
|
||||
/>
|
||||
<img
|
||||
alt={ product.short_description }
|
||||
className="wc-block-featured-product__background-image"
|
||||
src={ backgroundImageSrc }
|
||||
style={ backgroundImageStyle }
|
||||
onLoad={ ( e ) => {
|
||||
setBackgroundImageSize( {
|
||||
height: e.target?.naturalHeight,
|
||||
width: e.target?.naturalWidth,
|
||||
} );
|
||||
} }
|
||||
/>
|
||||
{ isImgElement && (
|
||||
<img
|
||||
alt={ product.short_description }
|
||||
className="wc-block-featured-product__background-image"
|
||||
src={ backgroundImageSrc }
|
||||
style={ backgroundImageStyle }
|
||||
onLoad={ ( e ) => {
|
||||
setBackgroundImageSize( {
|
||||
height: e.target?.naturalHeight,
|
||||
width: e.target?.naturalWidth,
|
||||
} );
|
||||
} }
|
||||
/>
|
||||
) }
|
||||
{ ! isImgElement && (
|
||||
<div
|
||||
className={ classnames(
|
||||
'wc-block-featured-product__background-image',
|
||||
{
|
||||
'has-parallax': hasParallax,
|
||||
}
|
||||
) }
|
||||
style={ backgroundDivStyle }
|
||||
/>
|
||||
) }
|
||||
<h2
|
||||
className="wc-block-featured-product__title"
|
||||
dangerouslySetInnerHTML={ {
|
||||
|
@ -736,6 +809,7 @@ export default compose( [
|
|||
state = {
|
||||
doUrlUpdate: false,
|
||||
};
|
||||
|
||||
componentDidUpdate() {
|
||||
const {
|
||||
attributes,
|
||||
|
@ -757,9 +831,11 @@ export default compose( [
|
|||
this.setState( { doUrlUpdate: false } );
|
||||
}
|
||||
}
|
||||
|
||||
triggerUrlUpdate = () => {
|
||||
this.setState( { doUrlUpdate: true } );
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ProductComponent
|
||||
|
@ -769,6 +845,7 @@ export default compose( [
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
return WrappedComponent;
|
||||
}, 'withUpdateButtonAttributes' ),
|
||||
] )( FeaturedProduct );
|
||||
|
|
|
@ -56,6 +56,14 @@
|
|||
"type": "string",
|
||||
"default": "none"
|
||||
},
|
||||
"hasParallax": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"isRepeated": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"mediaId": {
|
||||
"type": "number",
|
||||
"default": 0
|
||||
|
|
|
@ -10,6 +10,8 @@ export const example = {
|
|||
contentAlign: 'center',
|
||||
dimRatio: 50,
|
||||
editMode: false,
|
||||
hasParallax: false,
|
||||
isRepeated: false,
|
||||
height: getSetting( 'default_height', 500 ),
|
||||
mediaSrc: '',
|
||||
overlayColor: '#000000',
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.is-repeated {
|
||||
background-repeat: repeat;
|
||||
background-size: auto;
|
||||
}
|
||||
|
||||
// Applying image edits
|
||||
.is-applying {
|
||||
.components-spinner {
|
||||
|
@ -53,6 +58,7 @@
|
|||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
@ -133,6 +139,22 @@
|
|||
.wc-block-featured-product__background-image {
|
||||
@include absolute-stretch();
|
||||
object-fit: none;
|
||||
|
||||
&.has-parallax {
|
||||
background-attachment: fixed;
|
||||
|
||||
// Mobile Safari does not support fixed background attachment properly.
|
||||
// See also https://stackoverflow.com/questions/24154666/background-size-cover-not-working-on-ios
|
||||
// Chrome on Android does not appear to support the attachment at all: https://issuetracker.google.com/issues/36908439
|
||||
@supports (-webkit-overflow-scrolling: touch) {
|
||||
background-attachment: scroll;
|
||||
}
|
||||
|
||||
// Remove the appearance of scrolling based on OS-level animation preferences.
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
background-attachment: scroll;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wp-block-button.aligncenter {
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
export function calculateBackgroundImagePosition( coords ) {
|
||||
export function calculateImagePosition( coords ) {
|
||||
if ( ! coords ) return {};
|
||||
|
||||
const x = Math.round( coords.x * 100 );
|
||||
const y = Math.round( coords.y * 100 );
|
||||
|
||||
return {
|
||||
objectPosition: `${ x }% ${ y }%`,
|
||||
};
|
||||
return `${ x }% ${ y }%`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,3 +18,7 @@ export function dimRatioToClass( ratio ) {
|
|||
? null
|
||||
: `has-background-dim-${ 10 * Math.round( ratio / 10 ) }`;
|
||||
}
|
||||
|
||||
export function backgroundImageStyles( url ) {
|
||||
return { backgroundImage: `url(${ url })` };
|
||||
}
|
||||
|
|
|
@ -68,7 +68,9 @@ class FeaturedProduct extends AbstractDynamicBlock {
|
|||
}
|
||||
$attributes = wp_parse_args( $attributes, $this->defaults );
|
||||
|
||||
$attributes['height'] = isset( $attributes['height'] ) ? $attributes['height'] : wc_get_theme_support( 'featured_block::default_height', 500 );
|
||||
$default_height = wc_get_theme_support( 'featured_block::default_height', 500 );
|
||||
$min_height = $attributes['minHeight'] ?? $default_height;
|
||||
$attributes['height'] = $attributes['height'] ?? $default_height;
|
||||
|
||||
$title = sprintf(
|
||||
'<h2 class="wc-block-featured-product__title">%s</h2>',
|
||||
|
@ -92,13 +94,20 @@ class FeaturedProduct extends AbstractDynamicBlock {
|
|||
wp_kses_post( $product->get_price_html() )
|
||||
);
|
||||
|
||||
$styles = $this->get_styles( $attributes );
|
||||
$image_url = esc_url( $this->get_image_url( $attributes, $product ) );
|
||||
|
||||
$classes = $this->get_classes( $attributes );
|
||||
|
||||
$output = sprintf( '<div class="%1$s wp-block-woocommerce-featured-product" style="%2$s">', esc_attr( trim( $classes ) ), esc_attr( $styles ) );
|
||||
$output .= '<div class="wc-block-featured-product__wrapper">';
|
||||
$output = sprintf( '<div class="%1$s wp-block-woocommerce-featured-product">', esc_attr( trim( $classes ) ) );
|
||||
$output .= $this->render_wrapper( $attributes );
|
||||
$output .= $this->render_overlay( $attributes );
|
||||
$output .= $this->render_image( $attributes, $product );
|
||||
|
||||
if ( ! $attributes['isRepeated'] && ! $attributes['hasParallax'] ) {
|
||||
$output .= $this->render_image( $attributes, $product, $image_url );
|
||||
} else {
|
||||
$output .= $this->render_bg_image( $attributes, $image_url );
|
||||
}
|
||||
|
||||
$output .= $title;
|
||||
if ( $attributes['showDesc'] ) {
|
||||
$output .= $desc_str;
|
||||
|
@ -114,29 +123,39 @@ class FeaturedProduct extends AbstractDynamicBlock {
|
|||
}
|
||||
|
||||
/**
|
||||
* Renders the featured image
|
||||
* Returns the url of a product image
|
||||
*
|
||||
* @param array $attributes Block attributes. Default empty array.
|
||||
* @param \WC_Product $product Product object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function render_image( $attributes, $product ) {
|
||||
$style = '';
|
||||
private function get_image_url( $attributes, $product ) {
|
||||
$image_size = 'large';
|
||||
if ( 'none' !== $attributes['align'] || $attributes['height'] > 800 ) {
|
||||
$image_size = 'full';
|
||||
}
|
||||
|
||||
$style .= sprintf( 'object-fit: %s;', $attributes['imageFit'] );
|
||||
|
||||
if ( $attributes['mediaId'] ) {
|
||||
$image = wp_get_attachment_image_url( $attributes['mediaId'], $image_size );
|
||||
} else {
|
||||
$image = $this->get_image( $product, $image_size );
|
||||
return wp_get_attachment_image_url( $attributes['mediaId'], $image_size );
|
||||
}
|
||||
|
||||
if ( is_array( $attributes['focalPoint'] ) && 2 === count( $attributes['focalPoint'] ) ) {
|
||||
return $this->get_image( $product, $image_size );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the featured image
|
||||
*
|
||||
* @param array $attributes Block attributes. Default empty array.
|
||||
* @param \WC_Product $product Product object.
|
||||
* @param string $image_url Product image url.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function render_image( $attributes, $product, $image_url ) {
|
||||
$style = sprintf( 'object-fit: %s;', $attributes['imageFit'] );
|
||||
|
||||
if ( $this->hasFocalPoint( $attributes ) ) {
|
||||
$style .= sprintf(
|
||||
'object-position: %s%% %s%%;',
|
||||
$attributes['focalPoint']['x'] * 100,
|
||||
|
@ -144,11 +163,11 @@ class FeaturedProduct extends AbstractDynamicBlock {
|
|||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $image ) ) {
|
||||
if ( ! empty( $image_url ) ) {
|
||||
return sprintf(
|
||||
'<img alt="%1$s" class="wc-block-featured-product__background-image" src="%2$s" style="%3$s" />',
|
||||
wp_kses_post( $attributes['alt'] ?: $product->get_name() ),
|
||||
esc_url( $image ),
|
||||
$image_url,
|
||||
$style
|
||||
);
|
||||
}
|
||||
|
@ -156,6 +175,43 @@ class FeaturedProduct extends AbstractDynamicBlock {
|
|||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the featured image as a div background.
|
||||
*
|
||||
* @param array $attributes Block attributes. Default empty array.
|
||||
* @param string $image_url Product image url.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function render_bg_image( $attributes, $image_url ) {
|
||||
$styles = $this->get_bg_styles( $attributes, $image_url );
|
||||
|
||||
$classes = [ 'wc-block-featured-product__background-image' ];
|
||||
|
||||
if ( $attributes['hasParallax'] ) {
|
||||
$classes[] = ' has-parallax';
|
||||
}
|
||||
|
||||
return sprintf( '<div class="%1$s" style="%2$s" /></div>', implode( ' ', $classes ), $styles );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the image wrapper.
|
||||
*
|
||||
* @param array $attributes Block attributes. Default empty array.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function render_wrapper( $attributes ) {
|
||||
$min_height = $attributes['minHeight'] ?? wc_get_theme_support( 'featured_block::default_height', 500 );
|
||||
|
||||
if ( isset( $attributes['minHeight'] ) ) {
|
||||
$style = sprintf( 'min-height:%dpx;', intval( $min_height ) );
|
||||
}
|
||||
|
||||
return sprintf( '<div class="wc-block-featured-product__wrapper" style="%s">', esc_attr( $style ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the block overlay
|
||||
*
|
||||
|
@ -180,17 +236,29 @@ class FeaturedProduct extends AbstractDynamicBlock {
|
|||
/**
|
||||
* Get the styles for the wrapper element (background image, color).
|
||||
*
|
||||
* @param array $attributes Block attributes. Default empty array.
|
||||
* @param array $attributes Block attributes. Default empty array.
|
||||
* @param string $image_url Product image url.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_styles( $attributes ) {
|
||||
public function get_bg_styles( $attributes, $image_url ) {
|
||||
$style = '';
|
||||
|
||||
$min_height = isset( $attributes['minHeight'] ) ? $attributes['minHeight'] : wc_get_theme_support( 'featured_block::default_height', 500 );
|
||||
if ( $attributes['isRepeated'] || $attributes['hasParallax'] ) {
|
||||
$style .= "background-image: url($image_url);";
|
||||
}
|
||||
|
||||
if ( isset( $attributes['minHeight'] ) ) {
|
||||
$style .= sprintf( 'min-height:%dpx;', intval( $min_height ) );
|
||||
if ( ! $attributes['isRepeated'] ) {
|
||||
$style .= 'background-repeat: no-repeat;';
|
||||
$style .= 'background-size: ' . ( 'cover' === $attributes['imageFit'] ? $attributes['imageFit'] : 'auto' ) . ';';
|
||||
}
|
||||
|
||||
if ( $this->hasFocalPoint( $attributes ) ) {
|
||||
$style .= sprintf(
|
||||
'background-position: %s%% %s%%;',
|
||||
$attributes['focalPoint']['x'] * 100,
|
||||
$attributes['focalPoint']['y'] * 100
|
||||
);
|
||||
}
|
||||
|
||||
$global_style_style = StyleAttributesUtils::get_styles_by_attributes( $attributes, $this->global_style_wrapper );
|
||||
|
@ -228,6 +296,10 @@ class FeaturedProduct extends AbstractDynamicBlock {
|
|||
$classes[] = $attributes['className'];
|
||||
}
|
||||
|
||||
if ( $attributes['isRepeated'] ) {
|
||||
$classes[] = 'is-repeated';
|
||||
}
|
||||
|
||||
$global_style_classes = StyleAttributesUtils::get_classes_by_attributes( $attributes, $this->global_style_wrapper );
|
||||
$classes[] = $global_style_classes;
|
||||
|
||||
|
@ -255,6 +327,17 @@ class FeaturedProduct extends AbstractDynamicBlock {
|
|||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the focal point is defined for the block.
|
||||
*
|
||||
* @param array $attributes Block attributes. Default empty array.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasFocalPoint( $attributes ): bool {
|
||||
return is_array( $attributes['focalPoint'] ) && 2 === count( $attributes['focalPoint'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra data passed through from server to client for block.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue