Skip to content

Commit

Permalink
Put the Image block’s resizable box in a popover
Browse files Browse the repository at this point in the history
  • Loading branch information
stokesman committed Mar 2, 2025
1 parent d2e36e3 commit 0bf9296
Showing 1 changed file with 20 additions and 16 deletions.
36 changes: 20 additions & 16 deletions packages/block-library/src/image/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
privateApis as blockEditorPrivateApis,
BlockSettingsMenuControls,
} from '@wordpress/block-editor';
import { useCallback, useEffect, useMemo, useState } from '@wordpress/element';
import { useEffect, useMemo, useState } from '@wordpress/element';
import { __, _x, sprintf, isRTL } from '@wordpress/i18n';
import { getFilename } from '@wordpress/url';
import { getBlockBindingsSource, switchToBlockType } from '@wordpress/blocks';
Expand Down Expand Up @@ -287,18 +287,12 @@ export default function Image( {
const [ imageElement, setImageElement ] = useState();
const [ resizeDelta, setResizeDelta ] = useState( null );
const [ pixelSize, setPixelSize ] = useState( {} );
const [ offsetTop, setOffsetTop ] = useState( 0 );
const setResizeObserved = useResizeObserver( ( [ entry ] ) => {
if ( ! resizeDelta ) {
const [ box ] = entry.borderBoxSize;
setPixelSize( { width: box.inlineSize, height: box.blockSize } );
}
// This is usually 0 unless the image height is less than the line-height.
setOffsetTop( entry.target.offsetTop );
} );
const effectResizeableBoxPlacement = useCallback( () => {
setOffsetTop( imageElement?.offsetTop ?? 0 );
}, [ imageElement ] );
const setRefs = useMergeRefs( [ setImageElement, setResizeObserved ] );
const { allowResize = true } = context;
const { getBlock, getSettings } = useSelect( blockEditorStore );
Expand Down Expand Up @@ -1022,14 +1016,7 @@ export default function Image( {
/* eslint-enable no-lonely-if */
resizableBox = (
<ResizableBox
ref={ effectResizeableBoxPlacement }
style={ {
position: 'absolute',
// To match the vertical-align: bottom of the img (from style.scss)
// syncs the top with the img. This matters when the img height is
// less than the line-height.
inset: `${ offsetTop }px 0 0 0`,
} }
style={ { position: 'absolute' } }
size={ pixelSize }
minWidth={ minWidth }
maxWidth={ maxResizeWidth }
Expand All @@ -1042,6 +1029,10 @@ export default function Image( {
bottom: true,
left: showLeftHandle,
} }
// Ensures that resizing stops when the pointer is released.
onPointerDown={ ( { currentTarget, pointerId } ) => {
currentTarget.setPointerCapture( pointerId );
} }
onResizeStart={ () => {
toggleSelection( false );
} }
Expand Down Expand Up @@ -1131,7 +1122,20 @@ export default function Image( {
{ controls }
{ featuredImageControl }
{ img }
{ resizableBox }
{ resizableBox && (
<Popover
animate={ false }
focusOnMount={ false }
anchor={ imageElement }
__unstableSlotName="block-toolbar"
placement="top-start"
resize={ false }
flip={ false }
variant="unstyled"
>
{ resizableBox }
</Popover>
) }

<Caption
attributes={ attributes }
Expand Down

0 comments on commit 0bf9296

Please sign in to comment.