From 535c74f06253b0a8b3f682e40fc8188194fa4153 Mon Sep 17 00:00:00 2001 From: Amit Raj <77401999+amitraj2203@users.noreply.github.com> Date: Fri, 28 Jun 2024 11:50:48 +0530 Subject: [PATCH] Adds Aspect ratio control on Image blocks in Grids (#62891) Co-authored-by: amitraj2203 Co-authored-by: tellthemachines Co-authored-by: ndiego --- .../src/components/dimensions-tool/index.js | 186 +++++++++--------- packages/block-library/src/image/image.js | 29 ++- 2 files changed, 121 insertions(+), 94 deletions(-) diff --git a/packages/block-editor/src/components/dimensions-tool/index.js b/packages/block-editor/src/components/dimensions-tool/index.js index bbd3ac5ffb86e..49d0fe03b4cb4 100644 --- a/packages/block-editor/src/components/dimensions-tool/index.js +++ b/packages/block-editor/src/components/dimensions-tool/index.js @@ -58,6 +58,7 @@ function DimensionsTool( { scaleOptions, // Default options handled by ScaleTool. defaultScale = 'fill', // Match CSS default value for object-fit. unitsOptions, // Default options handled by UnitControl. + tools = [ 'aspectRatio', 'widthHeight', 'scale' ], } ) { // Coerce undefined and CSS default values to be null. const width = @@ -92,95 +93,102 @@ function DimensionsTool( { return ( <> - { - const nextValue = { ...value }; - - // 'auto' is CSS default, so it gets treated as null. - nextAspectRatio = - nextAspectRatio === 'auto' ? null : nextAspectRatio; - - setLastAspectRatio( nextAspectRatio ); - - // Update aspectRatio. - if ( ! nextAspectRatio ) { - delete nextValue.aspectRatio; - } else { - nextValue.aspectRatio = nextAspectRatio; - } - - // Auto-update scale. - if ( ! nextAspectRatio ) { - delete nextValue.scale; - } else if ( lastScale ) { - nextValue.scale = lastScale; - } else { - nextValue.scale = defaultScale; - setLastScale( defaultScale ); - } - - // Auto-update width and height. - if ( 'custom' !== nextAspectRatio && width && height ) { - delete nextValue.height; - } - - onChange( nextValue ); - } } - /> - { - const nextValue = { ...value }; - - // 'auto' is CSS default, so it gets treated as null. - nextWidth = nextWidth === 'auto' ? null : nextWidth; - nextHeight = nextHeight === 'auto' ? null : nextHeight; - - // Update width. - if ( ! nextWidth ) { - delete nextValue.width; - } else { - nextValue.width = nextWidth; - } - - // Update height. - if ( ! nextHeight ) { - delete nextValue.height; - } else { - nextValue.height = nextHeight; - } - - // Auto-update aspectRatio. - if ( nextWidth && nextHeight ) { - delete nextValue.aspectRatio; - } else if ( lastAspectRatio ) { - nextValue.aspectRatio = lastAspectRatio; - } else { - // No setting defaultAspectRatio here, because - // aspectRatio is optional in this scenario, - // unlike scale. - } - - // Auto-update scale. - if ( ! lastAspectRatio && !! nextWidth !== !! nextHeight ) { - delete nextValue.scale; - } else if ( lastScale ) { - nextValue.scale = lastScale; - } else { - nextValue.scale = defaultScale; - setLastScale( defaultScale ); - } - - onChange( nextValue ); - } } - /> - { showScaleControl && ( + { tools.includes( 'aspectRatio' ) && ( + { + const nextValue = { ...value }; + + // 'auto' is CSS default, so it gets treated as null. + nextAspectRatio = + nextAspectRatio === 'auto' ? null : nextAspectRatio; + + setLastAspectRatio( nextAspectRatio ); + + // Update aspectRatio. + if ( ! nextAspectRatio ) { + delete nextValue.aspectRatio; + } else { + nextValue.aspectRatio = nextAspectRatio; + } + + // Auto-update scale. + if ( ! nextAspectRatio ) { + delete nextValue.scale; + } else if ( lastScale ) { + nextValue.scale = lastScale; + } else { + nextValue.scale = defaultScale; + setLastScale( defaultScale ); + } + + // Auto-update width and height. + if ( 'custom' !== nextAspectRatio && width && height ) { + delete nextValue.height; + } + + onChange( nextValue ); + } } + /> + ) } + { tools.includes( 'widthHeight' ) && ( + { + const nextValue = { ...value }; + + // 'auto' is CSS default, so it gets treated as null. + nextWidth = nextWidth === 'auto' ? null : nextWidth; + nextHeight = nextHeight === 'auto' ? null : nextHeight; + + // Update width. + if ( ! nextWidth ) { + delete nextValue.width; + } else { + nextValue.width = nextWidth; + } + + // Update height. + if ( ! nextHeight ) { + delete nextValue.height; + } else { + nextValue.height = nextHeight; + } + + // Auto-update aspectRatio. + if ( nextWidth && nextHeight ) { + delete nextValue.aspectRatio; + } else if ( lastAspectRatio ) { + nextValue.aspectRatio = lastAspectRatio; + } else { + // No setting defaultAspectRatio here, because + // aspectRatio is optional in this scenario, + // unlike scale. + } + + // Auto-update scale. + if ( + ! lastAspectRatio && + !! nextWidth !== !! nextHeight + ) { + delete nextValue.scale; + } else if ( lastScale ) { + nextValue.scale = lastScale; + } else { + nextValue.scale = defaultScale; + setLastScale( defaultScale ); + } + + onChange( nextValue ); + } } + /> + ) } + { tools.includes( 'scale' ) && showScaleControl && ( image?.media_details?.sizes?.[ slug ]?.source_url @@ -405,6 +404,20 @@ export default function Image( { /> ); + const aspectRatioControl = ( + { + setAttributes( { + aspectRatio: newAspectRatio, + scale: 'cover', + } ); + } } + defaultAspectRatio="auto" + tools={ [ 'aspectRatio' ] } + /> + ); + const resetAll = () => { setAttributes( { alt: undefined, @@ -423,7 +436,10 @@ export default function Image( { resetAll={ resetAll } dropdownMenuProps={ dropdownMenuProps } > - { isResizable && dimensionsControl } + { isResizable && + ( parentLayoutType === 'grid' + ? aspectRatioControl + : dimensionsControl ) } ); @@ -738,7 +754,10 @@ export default function Image( { /> ) } - { isResizable && dimensionsControl } + { isResizable && + ( parentLayoutType === 'grid' + ? aspectRatioControl + : dimensionsControl ) } { !! imageSizeOptions.length && ( ); - } else if ( ! isResizable ) { + } else if ( ! isResizable || parentLayoutType === 'grid' ) { img = (
{ img }