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:
parent
642f227753
commit
87ce986719
|
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue