Skip to content

Commit

Permalink
feat: Add aspect ratio support to Media Text block
Browse files Browse the repository at this point in the history
  • Loading branch information
dhananjaykuber committed Jan 9, 2025
1 parent 85d9bad commit b34f799
Show file tree
Hide file tree
Showing 6 changed files with 248 additions and 14 deletions.
2 changes: 1 addition & 1 deletion docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ Set media and words side-by-side for a richer layout. ([Source](https://github.c
- **Name:** core/media-text
- **Category:** media
- **Supports:** align (full, wide), anchor, color (background, gradients, heading, link, text), interactivity (clientNavigation), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~
- **Attributes:** align, allowedBlocks, focalPoint, href, imageFill, isStackedOnMobile, linkClass, linkDestination, linkTarget, mediaAlt, mediaId, mediaLink, mediaPosition, mediaSizeSlug, mediaType, mediaUrl, mediaWidth, rel, useFeaturedImage, verticalAlignment
- **Attributes:** align, allowedBlocks, aspectRatio, focalPoint, href, imageFill, isStackedOnMobile, linkClass, linkDestination, linkTarget, mediaAlt, mediaId, mediaLink, mediaPosition, mediaSizeSlug, mediaType, mediaUrl, mediaWidth, rel, useFeaturedImage, verticalAlignment

## Unsupported

Expand Down
4 changes: 4 additions & 0 deletions packages/block-library/src/media-text/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@
"useFeaturedImage": {
"type": "boolean",
"default": false
},
"aspectRatio": {
"type": "string",
"default": "auto"
}
},
"usesContext": [ "postId", "postType" ],
Expand Down
143 changes: 130 additions & 13 deletions packages/block-library/src/media-text/deprecated.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { compose } from '@wordpress/compose';
/**
* Internal dependencies
*/
import { imageFillStyles } from './image-fill';
import { DEFAULT_MEDIA_SIZE_SLUG } from './constants';

const v1ToV5ImageFillStyles = ( url, focalPoint ) => {
Expand Down Expand Up @@ -212,6 +213,14 @@ const v7Attributes = {
},
};

const v8Attributes = {
...v7Attributes,
aspectRatio: {
type: 'string',
default: 'auto',
},
};

const v4ToV5Supports = {
anchor: true,
align: [ 'wide', 'full' ],
Expand Down Expand Up @@ -279,6 +288,119 @@ const v7Supports = {
},
};

// Version 8 with aspect ratio support
const v8 = {
attributes: v8Attributes,
supports: v7Supports,
usesContext: [ 'postId', 'postType' ],
save( { attributes } ) {
const {
isStackedOnMobile,
mediaAlt,
mediaPosition,
mediaType,
mediaUrl,
mediaWidth,
mediaId,
verticalAlignment,
imageFill,
focalPoint,
linkClass,
href,
linkTarget,
rel,
aspectRatio,
} = attributes;
const mediaSizeSlug =
attributes.mediaSizeSlug || DEFAULT_MEDIA_SIZE_SLUG;
const newRel = ! rel ? undefined : rel;

const imageClasses = clsx( {
[ `wp-image-${ mediaId }` ]: mediaId && mediaType === 'image',
[ `size-${ mediaSizeSlug }` ]: mediaId && mediaType === 'image',
} );

const positionStyles = imageFill
? imageFillStyles( mediaUrl, focalPoint )
: {};

let image = mediaUrl ? (
<img
src={ mediaUrl }
alt={ mediaAlt }
className={ imageClasses || null }
style={ positionStyles }
/>
) : null;

if ( href ) {
image = (
<a
className={ linkClass }
href={ href }
target={ linkTarget }
rel={ newRel }
>
{ image }
</a>
);
}

const mediaTypeRenders = {
image: () => image,
video: () => <video controls src={ mediaUrl } />,
};
const className = clsx( {
'has-media-on-the-right': 'right' === mediaPosition,
'is-stacked-on-mobile': isStackedOnMobile,
[ `is-vertically-aligned-${ verticalAlignment }` ]:
verticalAlignment,
'is-image-fill-element': imageFill,
'has-aspect-ratio': aspectRatio && aspectRatio !== 'auto',
[ `has-aspect-ratio-${ aspectRatio?.replace( ':', '-' ) }` ]:
aspectRatio && aspectRatio !== 'auto',
} );

let gridTemplateColumns;
if ( mediaWidth !== DEFAULT_MEDIA_WIDTH ) {
gridTemplateColumns =
'right' === mediaPosition
? `auto ${ mediaWidth }%`
: `${ mediaWidth }% auto`;
}
const style = {
gridTemplateColumns,
};

if ( 'right' === mediaPosition ) {
return (
<div { ...useBlockProps.save( { className, style } ) }>
<div
{ ...useInnerBlocksProps.save( {
className: 'wp-block-media-text__content',
} ) }
/>
<figure className="wp-block-media-text__media">
{ ( mediaTypeRenders[ mediaType ] || noop )() }
</figure>
</div>
);
}
return (
<div { ...useBlockProps.save( { className, style } ) }>
<figure className="wp-block-media-text__media">
{ ( mediaTypeRenders[ mediaType ] || noop )() }
</figure>
<div
{ ...useInnerBlocksProps.save( {
className: 'wp-block-media-text__content',
} ) }
/>
</div>
);
},
};

// Version with 'none' as the default alignment.
// See: https://github.com/WordPress/gutenberg/pull/64981
const v7 = {
Expand Down Expand Up @@ -311,11 +433,15 @@ const v7 = {
[ `size-${ mediaSizeSlug }` ]: mediaId && mediaType === 'image',
} );

const positionStyles = imageFill
? imageFillStyles( mediaUrl, focalPoint )
: {};
let image = mediaUrl ? (
<img
src={ mediaUrl }
alt={ mediaAlt }
className={ imageClasses || null }
style={ positionStyles }
/>
) : null;

Expand All @@ -341,11 +467,8 @@ const v7 = {
'is-stacked-on-mobile': isStackedOnMobile,
[ `is-vertically-aligned-${ verticalAlignment }` ]:
verticalAlignment,
'is-image-fill': imageFill,
'is-image-fill-element': imageFill,
} );
const backgroundStyles = imageFill
? v6ToV7ImageFillStyles( mediaUrl, focalPoint )
: {};

let gridTemplateColumns;
if ( mediaWidth !== DEFAULT_MEDIA_WIDTH ) {
Expand All @@ -366,21 +489,15 @@ const v7 = {
className: 'wp-block-media-text__content',
} ) }
/>
<figure
className="wp-block-media-text__media"
style={ backgroundStyles }
>
<figure className="wp-block-media-text__media">
{ ( mediaTypeRenders[ mediaType ] || noop )() }
</figure>
</div>
);
}
return (
<div { ...useBlockProps.save( { className, style } ) }>
<figure
className="wp-block-media-text__media"
style={ backgroundStyles }
>
<figure className="wp-block-media-text__media">
{ ( mediaTypeRenders[ mediaType ] || noop )() }
</figure>
<div
Expand Down Expand Up @@ -1058,4 +1175,4 @@ const v1 = {
},
};

export default [ v7, v6, v5, v4, v3, v2, v1 ];
export default [ v8, v7, v6, v5, v4, v3, v2, v1 ];
41 changes: 41 additions & 0 deletions packages/block-library/src/media-text/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
ToolbarButton,
ExternalLink,
FocalPointPicker,
SelectControl,
__experimentalToolsPanel as ToolsPanel,
__experimentalToolsPanelItem as ToolsPanelItem,
} from '@wordpress/components';
Expand Down Expand Up @@ -185,6 +186,7 @@ function MediaTextEdit( {
verticalAlignment,
allowedBlocks,
useFeaturedImage,
aspectRatio,
} = attributes;

const [ featuredImage ] = useEntityProp(
Expand Down Expand Up @@ -277,6 +279,9 @@ function MediaTextEdit( {
'is-stacked-on-mobile': isStackedOnMobile,
[ `is-vertically-aligned-${ verticalAlignment }` ]: verticalAlignment,
'is-image-fill-element': imageFill,
'has-aspect-ratio': aspectRatio && aspectRatio !== 'auto',
[ `has-aspect-ratio-${ aspectRatio?.replace( ':', '-' ) }` ]:
aspectRatio && aspectRatio !== 'auto',
} );
const widthString = `${ temporaryMediaWidth || mediaWidth }%`;
const gridTemplateColumns =
Expand Down Expand Up @@ -437,6 +442,42 @@ function MediaTextEdit( {
/>
</ToolsPanelItem>
) }
{ mediaType === 'image' && (
<ToolsPanelItem
label={ __( 'Aspect ratio' ) }
isShownByDefault
hasValue={ () => !! aspectRatio && aspectRatio !== 'auto' }
onDeselect={ () =>
setAttributes( {
aspectRatio: 'auto',
customAspectRatio: undefined,
} )
}
>
<SelectControl
__nextHasNoMarginBottom
__next40pxDefaultSize
label={ __( 'Aspect ratio' ) }
value={ aspectRatio }
options={ [
{ value: 'auto', label: __( 'Original' ) },
{ value: '1:1', label: __( 'Square - 1:1' ) },
{ value: '4:3', label: __( 'Standard - 4:3' ) },
{ value: '3:4', label: __( 'Portrait - 3:4' ) },
{ value: '3:2', label: __( 'Classic - 3:2' ) },
{
value: '2:3',
label: __( 'Classic Portrait - 2:3' ),
},
{ value: '16:9', label: __( 'Wide - 16:9' ) },
{ value: '9:16', label: __( 'Tall - 9:16' ) },
] }
onChange={ ( value ) =>
setAttributes( { aspectRatio: value } )
}
/>
</ToolsPanelItem>
) }
{ mediaType === 'image' && ! useFeaturedImage && (
<MediaTextResolutionTool
image={ image }
Expand Down
4 changes: 4 additions & 0 deletions packages/block-library/src/media-text/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default function save( { attributes } ) {
href,
linkTarget,
rel,
aspectRatio,
} = attributes;
const mediaSizeSlug = attributes.mediaSizeSlug || DEFAULT_MEDIA_SIZE_SLUG;
const newRel = ! rel ? undefined : rel;
Expand Down Expand Up @@ -77,6 +78,9 @@ export default function save( { attributes } ) {
'is-stacked-on-mobile': isStackedOnMobile,
[ `is-vertically-aligned-${ verticalAlignment }` ]: verticalAlignment,
'is-image-fill-element': imageFill,
'has-aspect-ratio': aspectRatio && aspectRatio !== 'auto',
[ `has-aspect-ratio-${ aspectRatio?.replace( ':', '-' ) }` ]:
aspectRatio && aspectRatio !== 'auto',
} );

let gridTemplateColumns;
Expand Down
68 changes: 68 additions & 0 deletions packages/block-library/src/media-text/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,74 @@
&.has-media-on-the-right {
grid-template-columns: 1fr 50%;
}

// Aspect ratio styles.
&.has-aspect-ratio {
position: relative;
overflow: hidden;

.wp-block-media-text__media {
img {
object-fit: cover;
}
}
}

&.has-aspect-ratio-1-1 {
.wp-block-media-text__media {
img {
aspect-ratio: 1/1;
}
}
}

&.has-aspect-ratio-4-3 {
.wp-block-media-text__media {
img {
aspect-ratio: 4/3;
}
}
}

&.has-aspect-ratio-3-4 {
.wp-block-media-text__media {
img {
aspect-ratio: 3/4;
}
}
}

&.has-aspect-ratio-3-2 {
.wp-block-media-text__media {
img {
aspect-ratio: 3/2;
}
}
}

&.has-aspect-ratio-2-3 {
.wp-block-media-text__media {
img {
aspect-ratio: 2/3;
}
}
}

&.has-aspect-ratio-16-9 {
.wp-block-media-text__media {
img {
aspect-ratio: 16/9;
}
}
}

&.has-aspect-ratio-9-16 {
.wp-block-media-text__media {
img {
aspect-ratio: 9/16;
}
}
}
}

.wp-block-media-text.is-vertically-aligned-top {
Expand Down

0 comments on commit b34f799

Please sign in to comment.