Fix image editor in Featured Product/Category blocks on WP 6.2 (https://github.com/woocommerce/woocommerce-blocks/pull/9142)

This commit is contained in:
Albert Juhé Lluveras 2023-04-20 15:56:42 +02:00 committed by GitHub
parent 642f227753
commit 87ce986719
1 changed files with 81 additions and 12 deletions

View File

@ -3,6 +3,7 @@
/** /**
* External dependencies * External dependencies
*/ */
import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
import { WP_REST_API_Category } from 'wp-types'; import { WP_REST_API_Category } from 'wp-types';
import { ProductResponseItem } from '@woocommerce/types'; import { ProductResponseItem } from '@woocommerce/types';
import { import {
@ -18,7 +19,7 @@ import { BLOCK_NAMES, DEFAULT_EDITOR_SIZE } from './constants';
import { EditorBlock } from './types'; import { EditorBlock } from './types';
import { useBackgroundImage } from './use-background-image'; import { useBackgroundImage } from './use-background-image';
type MediaAttributes = { mediaId: number; mediaSrc: string }; type MediaAttributes = { align: string; mediaId: number; mediaSrc: string };
type MediaSize = { height: number; width: number }; type MediaSize = { height: number; width: number };
interface WithImageEditorRequiredProps< T > { interface WithImageEditorRequiredProps< T > {
@ -45,24 +46,70 @@ type WithImageEditorProps< T extends EditorBlock< T > > =
| ( T & WithImageEditorProductProps< T > ); | ( T & WithImageEditorProductProps< T > );
interface ImageEditorProps { interface ImageEditorProps {
align: string;
backgroundImageId: number; backgroundImageId: number;
backgroundImageSize: MediaSize; backgroundImageSize: MediaSize;
backgroundImageSrc: string; backgroundImageSrc: string;
containerRef: React.RefObject< HTMLDivElement >;
isEditingImage: boolean; isEditingImage: boolean;
setAttributes: ( attrs: MediaAttributes ) => void; setAttributes: ( attrs: MediaAttributes ) => void;
setIsEditingImage: ( value: boolean ) => void; setIsEditingImage: ( value: boolean ) => void;
} }
// Adapted from:
// https://github.com/WordPress/gutenberg/blob/v15.6.1/packages/block-library/src/image/use-client-width.js
function useClientWidth(
ref: React.RefObject< HTMLDivElement >,
dependencies: string[]
) {
const [ clientWidth, setClientWidth ]: [
number | undefined,
Dispatch< SetStateAction< number | undefined > >
] = useState();
const calculateClientWidth = useCallback( () => {
setClientWidth( ref.current?.clientWidth );
}, [ ref ] );
useEffect( calculateClientWidth, [
calculateClientWidth,
...dependencies,
] );
useEffect( () => {
if ( ! ref.current ) {
return;
}
const { defaultView } = ref.current.ownerDocument;
if ( ! defaultView ) {
return;
}
defaultView.addEventListener( 'resize', calculateClientWidth );
return () => {
defaultView.removeEventListener( 'resize', calculateClientWidth );
};
}, [ ref, calculateClientWidth ] );
return clientWidth;
}
export const ImageEditor = ( { export const ImageEditor = ( {
align,
backgroundImageId, backgroundImageId,
backgroundImageSize, backgroundImageSize,
backgroundImageSrc, backgroundImageSrc,
containerRef,
isEditingImage, isEditingImage,
setAttributes, setAttributes,
setIsEditingImage, setIsEditingImage,
}: ImageEditorProps ) => { }: ImageEditorProps ) => {
return ( const clientWidth = useClientWidth( containerRef, [ align ] );
<>
// Fallback for WP 6.1 or lower. In WP 6.2. ImageEditingProvider was merged
// with ImageEditor, see: https://github.com/WordPress/gutenberg/pull/47171
if ( typeof ImageEditingProvider === 'function' ) {
return (
<ImageEditingProvider <ImageEditingProvider
id={ backgroundImageId } id={ backgroundImageId }
url={ backgroundImageSrc } url={ backgroundImageSrc }
@ -88,7 +135,23 @@ export const ImageEditor = ( {
} }
/> />
</ImageEditingProvider> </ImageEditingProvider>
</> );
}
return (
<GutenbergImageEditor
id={ backgroundImageId }
url={ backgroundImageSrc }
height={ backgroundImageSize.height || DEFAULT_EDITOR_SIZE.height }
width={ backgroundImageSize.width || DEFAULT_EDITOR_SIZE.width }
naturalHeight={ backgroundImageSize.height }
naturalWidth={ backgroundImageSize.width }
onSaveImage={ ( { id, url }: { id: number; url: string } ) => {
setAttributes( { mediaId: id, mediaSrc: url } );
} }
onFinishEditing={ () => setIsEditingImage( false ) }
clientWidth={ clientWidth }
/>
); );
}; };
@ -97,6 +160,8 @@ export const withImageEditor =
( props: WithImageEditorProps< T > ) => { ( props: WithImageEditorProps< T > ) => {
const [ isEditingImage, setIsEditingImage ] = props.useEditingImage; const [ isEditingImage, setIsEditingImage ] = props.useEditingImage;
const ref = useRef< HTMLDivElement >( null );
const { attributes, backgroundImageSize, name, setAttributes } = props; const { attributes, backgroundImageSize, name, setAttributes } = props;
const { mediaId, mediaSrc } = attributes; const { mediaId, mediaSrc } = attributes;
const item = const item =
@ -113,14 +178,18 @@ export const withImageEditor =
if ( isEditingImage ) { if ( isEditingImage ) {
return ( return (
<ImageEditor <div ref={ ref }>
backgroundImageId={ backgroundImageId } <ImageEditor
backgroundImageSize={ backgroundImageSize } align={ attributes.align }
backgroundImageSrc={ backgroundImageSrc } backgroundImageId={ backgroundImageId }
isEditingImage={ isEditingImage } backgroundImageSize={ backgroundImageSize }
setAttributes={ setAttributes } backgroundImageSrc={ backgroundImageSrc }
setIsEditingImage={ setIsEditingImage } containerRef={ ref }
/> isEditingImage={ isEditingImage }
setAttributes={ setAttributes }
setIsEditingImage={ setIsEditingImage }
/>
</div>
); );
} }