Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Commit 0db82f8

Browse files
authored
Fix image editor in Featured Product/Category blocks on WP 6.2 (#9142)
1 parent cfd79f5 commit 0db82f8

File tree

1 file changed

+81
-12
lines changed

1 file changed

+81
-12
lines changed

assets/js/blocks/featured-items/image-editor.tsx

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
/**
44
* External dependencies
55
*/
6+
import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
67
import { WP_REST_API_Category } from 'wp-types';
78
import { ProductResponseItem } from '@woocommerce/types';
89
import {
@@ -18,7 +19,7 @@ import { BLOCK_NAMES, DEFAULT_EDITOR_SIZE } from './constants';
1819
import { EditorBlock } from './types';
1920
import { useBackgroundImage } from './use-background-image';
2021

21-
type MediaAttributes = { mediaId: number; mediaSrc: string };
22+
type MediaAttributes = { align: string; mediaId: number; mediaSrc: string };
2223
type MediaSize = { height: number; width: number };
2324

2425
interface WithImageEditorRequiredProps< T > {
@@ -45,24 +46,70 @@ type WithImageEditorProps< T extends EditorBlock< T > > =
4546
| ( T & WithImageEditorProductProps< T > );
4647

4748
interface ImageEditorProps {
49+
align: string;
4850
backgroundImageId: number;
4951
backgroundImageSize: MediaSize;
5052
backgroundImageSrc: string;
53+
containerRef: React.RefObject< HTMLDivElement >;
5154
isEditingImage: boolean;
5255
setAttributes: ( attrs: MediaAttributes ) => void;
5356
setIsEditingImage: ( value: boolean ) => void;
5457
}
5558

59+
// Adapted from:
60+
// https://github.com/WordPress/gutenberg/blob/v15.6.1/packages/block-library/src/image/use-client-width.js
61+
function useClientWidth(
62+
ref: React.RefObject< HTMLDivElement >,
63+
dependencies: string[]
64+
) {
65+
const [ clientWidth, setClientWidth ]: [
66+
number | undefined,
67+
Dispatch< SetStateAction< number | undefined > >
68+
] = useState();
69+
70+
const calculateClientWidth = useCallback( () => {
71+
setClientWidth( ref.current?.clientWidth );
72+
}, [ ref ] );
73+
74+
useEffect( calculateClientWidth, [
75+
calculateClientWidth,
76+
...dependencies,
77+
] );
78+
useEffect( () => {
79+
if ( ! ref.current ) {
80+
return;
81+
}
82+
const { defaultView } = ref.current.ownerDocument;
83+
84+
if ( ! defaultView ) {
85+
return;
86+
}
87+
defaultView.addEventListener( 'resize', calculateClientWidth );
88+
89+
return () => {
90+
defaultView.removeEventListener( 'resize', calculateClientWidth );
91+
};
92+
}, [ ref, calculateClientWidth ] );
93+
94+
return clientWidth;
95+
}
96+
5697
export const ImageEditor = ( {
98+
align,
5799
backgroundImageId,
58100
backgroundImageSize,
59101
backgroundImageSrc,
102+
containerRef,
60103
isEditingImage,
61104
setAttributes,
62105
setIsEditingImage,
63106
}: ImageEditorProps ) => {
64-
return (
65-
<>
107+
const clientWidth = useClientWidth( containerRef, [ align ] );
108+
109+
// Fallback for WP 6.1 or lower. In WP 6.2. ImageEditingProvider was merged
110+
// with ImageEditor, see: https://github.com/WordPress/gutenberg/pull/47171
111+
if ( typeof ImageEditingProvider === 'function' ) {
112+
return (
66113
<ImageEditingProvider
67114
id={ backgroundImageId }
68115
url={ backgroundImageSrc }
@@ -88,7 +135,23 @@ export const ImageEditor = ( {
88135
}
89136
/>
90137
</ImageEditingProvider>
91-
</>
138+
);
139+
}
140+
141+
return (
142+
<GutenbergImageEditor
143+
id={ backgroundImageId }
144+
url={ backgroundImageSrc }
145+
height={ backgroundImageSize.height || DEFAULT_EDITOR_SIZE.height }
146+
width={ backgroundImageSize.width || DEFAULT_EDITOR_SIZE.width }
147+
naturalHeight={ backgroundImageSize.height }
148+
naturalWidth={ backgroundImageSize.width }
149+
onSaveImage={ ( { id, url }: { id: number; url: string } ) => {
150+
setAttributes( { mediaId: id, mediaSrc: url } );
151+
} }
152+
onFinishEditing={ () => setIsEditingImage( false ) }
153+
clientWidth={ clientWidth }
154+
/>
92155
);
93156
};
94157

@@ -97,6 +160,8 @@ export const withImageEditor =
97160
( props: WithImageEditorProps< T > ) => {
98161
const [ isEditingImage, setIsEditingImage ] = props.useEditingImage;
99162

163+
const ref = useRef< HTMLDivElement >( null );
164+
100165
const { attributes, backgroundImageSize, name, setAttributes } = props;
101166
const { mediaId, mediaSrc } = attributes;
102167
const item =
@@ -113,14 +178,18 @@ export const withImageEditor =
113178

114179
if ( isEditingImage ) {
115180
return (
116-
<ImageEditor
117-
backgroundImageId={ backgroundImageId }
118-
backgroundImageSize={ backgroundImageSize }
119-
backgroundImageSrc={ backgroundImageSrc }
120-
isEditingImage={ isEditingImage }
121-
setAttributes={ setAttributes }
122-
setIsEditingImage={ setIsEditingImage }
123-
/>
181+
<div ref={ ref }>
182+
<ImageEditor
183+
align={ attributes.align }
184+
backgroundImageId={ backgroundImageId }
185+
backgroundImageSize={ backgroundImageSize }
186+
backgroundImageSrc={ backgroundImageSrc }
187+
containerRef={ ref }
188+
isEditingImage={ isEditingImage }
189+
setAttributes={ setAttributes }
190+
setIsEditingImage={ setIsEditingImage }
191+
/>
192+
</div>
124193
);
125194
}
126195

0 commit comments

Comments
 (0)