diff --git a/assets/js/blocks/featured-product/block.js b/assets/js/blocks/featured-product/block.js index 3dd132944de..9127f517a48 100644 --- a/assets/js/blocks/featured-product/block.js +++ b/assets/js/blocks/featured-product/block.js @@ -3,7 +3,7 @@ /** * External dependencies */ -import { useCallback, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; import { __ } from '@wordpress/i18n'; import { AlignmentToolbar, @@ -13,6 +13,8 @@ import { MediaReplaceFlow, RichText, __experimentalGetSpacingClassesAndStyles as getSpacingClassesAndStyles, + __experimentalImageEditingProvider as ImageEditingProvider, + __experimentalImageEditor as ImageEditor, __experimentalPanelColorGradientSettings as PanelColorGradientSettings, __experimentalUseGradient as useGradient, } from '@wordpress/block-editor'; @@ -28,6 +30,7 @@ import { Spinner, TextareaControl, ToggleControl, + ToolbarButton, ToolbarGroup, withSpokenMessages, __experimentalToggleGroupControl as ToggleGroupControl, @@ -42,7 +45,7 @@ import ProductControl from '@woocommerce/editor-components/product-control'; import ErrorPlaceholder from '@woocommerce/editor-components/error-placeholder'; import TextToolbarButton from '@woocommerce/editor-components/text-toolbar-button'; import { withProduct } from '@woocommerce/block-hocs'; -import { Icon, starEmpty } from '@wordpress/icons'; +import { crop, Icon, starEmpty } from '@wordpress/icons'; /** * Internal dependencies @@ -54,6 +57,11 @@ import { } from '../../utils/products'; import { useThrottle } from '../../utils/useThrottle'; +const DEFAULT_EDITOR_SIZE = { + height: 500, + width: 500, +}; + export const ConstrainedResizable = ( { className = '', onResize, @@ -112,10 +120,18 @@ const FeaturedProduct = ( { setAttributes, triggerUrlUpdate = () => void null, } ) => { + const { mediaId, mediaSrc } = attributes; + + const [ isEditingImage, setIsEditingImage ] = useState( false ); + const [ backgroundImageSize, setBackgroundImageSize ] = useState( {} ); const { setGradient } = useGradient( { gradientAttribute: 'overlayGradient', customGradientAttribute: 'overlayGradient', } ); + + const backgroundImageSrc = mediaSrc || getImageSrcFromProduct( product ); + const backgroundImageId = mediaId || getImageIdFromProduct( product ); + const onResize = useCallback( ( _event, _direction, elt ) => { setAttributes( { minHeight: parseInt( elt.style.height, 10 ) } ); @@ -132,6 +148,10 @@ const FeaturedProduct = ( { /> ); + useEffect( () => { + setIsEditingImage( false ); + }, [ isSelected ] ); + const renderEditMode = () => { const onDone = () => { setAttributes( { editMode: false } ); @@ -182,8 +202,7 @@ const FeaturedProduct = ( { }; const getBlockControls = () => { - const { contentAlign, editMode, mediaSrc } = attributes; - const mediaId = attributes.mediaId || getImageIdFromProduct( product ); + const { contentAlign, editMode } = attributes; return ( @@ -194,8 +213,18 @@ const FeaturedProduct = ( { } } /> + { ! isEditingImage && ( + setIsEditingImage( true ) } + icon={ crop } + label={ __( + 'Edit product image', + 'woo-gutenberg-products-block' + ) } + /> + ) } { @@ -206,7 +235,7 @@ const FeaturedProduct = ( { } } allowedTypes={ [ 'image' ] } /> - { mediaId && mediaSrc ? ( + { backgroundImageId && mediaSrc ? ( setAttributes( { mediaId: 0, mediaSrc: '' } ) @@ -426,7 +455,6 @@ const FeaturedProduct = ( { dimRatio, focalPoint, imageFit, - mediaSrc, minHeight, overlayColor, overlayGradient, @@ -456,9 +484,6 @@ const FeaturedProduct = ( { minHeight, }; - const backgroundImageSrc = - mediaSrc || getImageSrcFromProduct( product ); - const backgroundImageStyle = { ...calculateBackgroundImagePosition( focalPoint ), objectFit: imageFit, @@ -491,6 +516,12 @@ const FeaturedProduct = ( { className="wc-block-featured-product__background-image" src={ backgroundImageSrc } style={ backgroundImageStyle } + onLoad={ ( e ) => { + setBackgroundImageSize( { + height: e.target?.naturalHeight, + width: e.target?.naturalWidth, + } ); + } } />

+ { + setAttributes( { mediaId: id, mediaSrc: url } ); + } } + isEditing={ isEditingImage } + onFinishEditing={ () => setIsEditingImage( false ) } + > + + + + ); + } + return ( <> { getBlockControls() } diff --git a/assets/js/blocks/featured-product/style.scss b/assets/js/blocks/featured-product/style.scss index 093c1eb6ae9..75b71078946 100644 --- a/assets/js/blocks/featured-product/style.scss +++ b/assets/js/blocks/featured-product/style.scss @@ -16,6 +16,21 @@ height: auto !important; } } + + // Applying image edits + .is-applying { + .components-spinner { + position: absolute; + top: 50%; + left: 50%; + margin-top: -9px; + margin-left: -9px; + } + + img { + opacity: 0.3; + } + } } .wc-block-featured-product {