Skip to content

Commit

Permalink
Fix alignment issues
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 committed Aug 29, 2024
1 parent 5831ea9 commit 7493311
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 41 deletions.
102 changes: 66 additions & 36 deletions packages/block-library/src/image/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ import {
__experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles,
useBlockEditingMode,
} from '@wordpress/block-editor';
import { useEffect, useRef, useState } from '@wordpress/element';
import { useEffect, useRef, useState, cloneElement } 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
Expand Down Expand Up @@ -108,7 +109,9 @@ export function ImageEdit( {
metadata,
} = attributes;
const [ temporaryURL, setTemporaryURL ] = useState( attributes.blob );
const containerRef = useRef();

const [ contentResizeListener, { width: containerWidth } ] =
useResizeObserver();

const altRef = useRef();
useEffect( () => {
Expand Down Expand Up @@ -293,10 +296,7 @@ export function ImageEdit( {
Object.keys( borderProps.style ).length > 0 ),
} );

const blockProps = useBlockProps( {
ref: containerRef,
className: classes,
} );
const blockProps = useBlockProps( { className: classes } );

// Much of this description is duplicated from MediaPlaceholder.
const { lockUrlControls = false, lockUrlControlsMessage } = useSelect(
Expand Down Expand Up @@ -368,36 +368,66 @@ export function ImageEdit( {
};

return (
<figure { ...blockProps }>
<Image
temporaryURL={ temporaryURL }
attributes={ attributes }
setAttributes={ setAttributes }
isSingleSelected={ isSingleSelected }
insertBlocksAfter={ insertBlocksAfter }
onReplace={ onReplace }
onSelectImage={ onSelectImage }
onSelectURL={ onSelectURL }
onUploadError={ onUploadError }
context={ context }
clientId={ clientId }
blockEditingMode={ blockEditingMode }
parentLayoutType={ parentLayout?.type }
getContainerWidth={ () => containerRef.current.offsetWidth }
/>
<MediaPlaceholder
icon={ <BlockIcon icon={ icon } /> }
onSelect={ onSelectImage }
onSelectURL={ onSelectURL }
onError={ onUploadError }
placeholder={ placeholder }
accept="image/*"
allowedTypes={ ALLOWED_MEDIA_TYPES }
value={ { id, src } }
mediaPreview={ mediaPreview }
disableMediaButtons={ temporaryURL || url }
/>
</figure>
<>
<figure { ...blockProps }>
<Image
temporaryURL={ temporaryURL }
attributes={ attributes }
setAttributes={ setAttributes }
isSingleSelected={ isSingleSelected }
insertBlocksAfter={ insertBlocksAfter }
onReplace={ onReplace }
onSelectImage={ onSelectImage }
onSelectURL={ onSelectURL }
onUploadError={ onUploadError }
context={ context }
clientId={ clientId }
blockEditingMode={ blockEditingMode }
parentLayoutType={ parentLayout?.type }
maxContentWidth={ align ? containerWidth : undefined }
/>
<MediaPlaceholder
icon={ <BlockIcon icon={ icon } /> }
onSelect={ onSelectImage }
onSelectURL={ onSelectURL }
onError={ onUploadError }
placeholder={ placeholder }
accept="image/*"
allowedTypes={ ALLOWED_MEDIA_TYPES }
value={ { id, src } }
mediaPreview={ mediaPreview }
disableMediaButtons={ temporaryURL || url }
/>
</figure>
{
// Only render the resize observer if the image is aligned,
// because 100% width won't work with aligned elements (table and float).
[ 'left', 'right', 'center' ].includes( align ) ? (
// 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
// A trick to take the padding of the parent into account when calculating the max width.
<div
aria-hidden="true"
style={ {
position: 'absolute',
boxSizing: 'border-box',
inset: 0,
width: '100%',
height: 0,
paddingInline: 'inherit',
margin: 0,
} }
>
{ cloneElement( contentResizeListener, {
style: {
...contentResizeListener.props.style,
position: 'relative',
},
} ) }
</div>
) : null
}
</>
);
}

Expand Down
5 changes: 5 additions & 0 deletions packages/block-library/src/image/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ figure.wp-block-image:not(.wp-block) {
text-align: center;
}

// Relatively position the alignment container to support the content resizer.
.wp-block[data-align]:has(> .wp-block-image) {
position: relative;
}

.wp-block-image__crop-area {
position: relative;
max-width: 100%;
Expand Down
24 changes: 19 additions & 5 deletions packages/block-library/src/image/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export default function Image( {
clientId,
blockEditingMode,
parentLayoutType,
getContainerWidth,
maxContentWidth,
} ) {
const {
url = '',
Expand Down Expand Up @@ -971,8 +971,11 @@ export default function Image( {
} }
showHandle={ isSingleSelected }
minWidth={ minWidth }
maxWidth="100%"
maxWidth={ maxContentWidth || '100%' }
minHeight={ minHeight }
maxHeight={
maxContentWidth ? maxContentWidth / ratio : undefined
}
lockAspectRatio={ ratio }
enable={ {
top: false,
Expand All @@ -984,14 +987,25 @@ export default function Image( {
onResizeStop={ ( event, direction, elt ) => {
onResizeStop();

const maxContentWidth = getContainerWidth();
let maxWidth = maxContentWidth;
if ( ! maxWidth ) {
const parentElement = elt.parentElement;
const parentBox = parentElement.getBoundingClientRect();
const parentStyle =
parentElement.ownerDocument.defaultView.getComputedStyle(
parentElement
);
maxWidth =
parentBox.width -
parseFloat( parentStyle.paddingInline );
}

// Clear hardcoded width if the resized width is close to the max-content width.
if (
// Only do this if the image is bigger than the container to prevent it from being squished.
// TODO: Remove this check if the image support setting 100% width.
naturalWidth >= maxContentWidth &&
Math.abs( elt.offsetWidth - maxContentWidth ) < 10
naturalWidth >= maxWidth &&
Math.abs( elt.offsetWidth - maxWidth ) < 10
) {
setAttributes( {
width: undefined,
Expand Down

0 comments on commit 7493311

Please sign in to comment.