Skip to content

Commit

Permalink
Create a new hook
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 committed Aug 30, 2024
1 parent 1b3e4ac commit b91cc18
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 14 deletions.
18 changes: 4 additions & 14 deletions packages/block-library/src/image/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ import {
__experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles,
useBlockEditingMode,
} from '@wordpress/block-editor';
import { useEffect, useRef, useState, cloneElement } from '@wordpress/element';
import { useEffect, useRef, useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { image as icon, plugins as pluginsIcon } from '@wordpress/icons';
import { store as noticesStore } from '@wordpress/notices';
import { useResizeObserver } from '@wordpress/compose';

/**
* Internal dependencies
*/
import { unlock } from '../lock-unlock';
import { useUploadMediaFromBlobURL } from '../utils/hooks';
import Image from './image';
import { useMaxWidthObserver } from './use-max-width-observer';

/**
* Module constants
Expand Down Expand Up @@ -110,8 +110,7 @@ export function ImageEdit( {
} = attributes;
const [ temporaryURL, setTemporaryURL ] = useState( attributes.blob );

const [ contentResizeListener, { width: maxContentWidth } ] =
useResizeObserver();
const [ maxWidthObserver, maxContentWidth ] = useMaxWidthObserver();

const altRef = useRef();
useEffect( () => {
Expand Down Expand Up @@ -402,16 +401,7 @@ export function ImageEdit( {
{
// The listener cannot be placed as the first element as it will break the in-between inserter.
// See https://github.com/WordPress/gutenberg/blob/71134165868298fc15e22896d0c28b41b3755ff7/packages/block-editor/src/components/block-list/use-in-between-inserter.js#L120
isSingleSelected &&
cloneElement( contentResizeListener, {
// Some themes set max-width on blocks.
className: 'wp-block',
style: {
...contentResizeListener.props.style,
height: 0,
margin: 0,
},
} )
isSingleSelected && maxWidthObserver
}
</>
);
Expand Down
62 changes: 62 additions & 0 deletions packages/block-library/src/image/use-max-width-observer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* WordPress dependencies
*/
import { cloneElement, useRef, useMemo } from '@wordpress/element';
import { useResizeObserver } from '@wordpress/compose';

function useMaxWidthObserver() {
const [ contentResizeListener, { width } ] = useResizeObserver();
const observerRef = useRef();

const maxWidthObserver = (
<div
// Some themes set max-width on blocks.
className="wp-block"
aria-hidden="true"
style={ {
position: 'absolute',
inset: 0,
width: '100%',
height: 0,
margin: 0,
} }
ref={ observerRef }
>
{ cloneElement( contentResizeListener, {
style: {
...contentResizeListener.props.style,
position: 'relative',
},
} ) }
</div>
);

const maxWidth = useMemo( () => {
const observer = observerRef.current;
if ( ! observer ) {
return width;
}

const win = observer.ownerDocument.defaultView;
const observerStyle = win.getComputedStyle( observer );
const parentStyle = win.getComputedStyle( observer.parentElement );

const isParentBorderBox = parentStyle.boxSizing === 'border-box';
const paddingInline = isParentBorderBox
? 0
: parseFloat( parentStyle.paddingLeft ) +
parseFloat( parentStyle.paddingRight );

const observerMaxWidth = parseFloat( observerStyle.maxWidth );
const contentWidth =
width - ( Number.isNaN( paddingInline ) ? 0 : paddingInline );

return Number.isNaN( observerMaxWidth )
? contentWidth
: Math.min( contentWidth, observerMaxWidth );
}, [ width ] );

return [ maxWidthObserver, maxWidth ];
}

export { useMaxWidthObserver };

0 comments on commit b91cc18

Please sign in to comment.