From b91cc1887f8e1ccb6645f440ec2beb12418052ab Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Fri, 30 Aug 2024 17:25:31 +0800 Subject: [PATCH] Create a new hook --- packages/block-library/src/image/edit.js | 18 ++---- .../src/image/use-max-width-observer.js | 62 +++++++++++++++++++ 2 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 packages/block-library/src/image/use-max-width-observer.js diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js index 7902a39aedc13d..b3de9ba56a84ab 100644 --- a/packages/block-library/src/image/edit.js +++ b/packages/block-library/src/image/edit.js @@ -19,11 +19,10 @@ 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 @@ -31,6 +30,7 @@ import { useResizeObserver } from '@wordpress/compose'; import { unlock } from '../lock-unlock'; import { useUploadMediaFromBlobURL } from '../utils/hooks'; import Image from './image'; +import { useMaxWidthObserver } from './use-max-width-observer'; /** * Module constants @@ -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( () => { @@ -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 } ); diff --git a/packages/block-library/src/image/use-max-width-observer.js b/packages/block-library/src/image/use-max-width-observer.js new file mode 100644 index 00000000000000..6889ac6266709e --- /dev/null +++ b/packages/block-library/src/image/use-max-width-observer.js @@ -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 = ( + + ); + + 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 };