Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try replacing flex with grid in Gallery block. #60022

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ Display multiple images in a rich gallery. ([Source](https://github.com/WordPres
- **Name:** core/gallery
- **Category:** media
- **Allowed Blocks:** core/image
- **Supports:** align, anchor, color (background, gradients, ~~text~~), interactivity (clientNavigation), layout (default, ~~allowEditing~~, ~~allowInheriting~~, ~~allowSwitching~~), spacing (blockGap, margin, padding), units (em, px, rem, vh, vw), ~~html~~
- **Supports:** align, anchor, color (background, gradients, ~~text~~), interactivity (clientNavigation), layout (allowSizingOnChildren, default), spacing (blockGap, margin, padding), units (em, px, rem, vh, vw), ~~html~~
- **Attributes:** allowResize, caption, columns, fixedHeight, ids, imageCrop, images, linkTarget, linkTo, randomOrder, shortCodeTransforms, sizeSlug

## Group
Expand Down
7 changes: 3 additions & 4 deletions packages/block-library/src/gallery/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,10 @@
"gradients": true
},
"layout": {
"allowSwitching": false,
"allowInheriting": false,
"allowEditing": false,
"allowSizingOnChildren": true,
"default": {
"type": "flex"
"type": "grid",
"columnCount": 3
}
},
"interactivity": {
Expand Down
119 changes: 107 additions & 12 deletions packages/block-library/src/gallery/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,52 @@ const MOBILE_CONTROL_PROPS_RANGE_CONTROL = Platform.isNative
const DEFAULT_BLOCK = { name: 'core/image' };
const EMPTY_ARRAY = [];

// Thanks StackOverflow! https://stackoverflow.com/questions/17445231/js-how-to-find-the-greatest-common-divisor
const gcd = ( a, b ) => {
if ( ! b ) {
return a;
}

return gcd( b, a % b );
};

const lcm = ( a, b ) => {
return ( a * b ) / gcd( a, b );
};

/*
* Returns an array of image column-span attributes to apply to each image block.
* The spans are based on the column count and the number of images, so that each
* row in the grid is filled to its full width.
*/
function getColumnSpans( columns = 3, images ) {
if ( images < columns ) {
return {
minimumColumnCount: images.length,
columnSpans: Array( images.length ).fill( 1 ),
};
}
const remainder = images % columns;
const minimumColumnCount = lcm( columns, remainder );
const multiples = images - remainder;
const multiplesSpans = minimumColumnCount / columns;
const remainderSpans = minimumColumnCount / remainder;

const columnSpans = [];
for ( let i = 0; i < images; i++ ) {
if ( i < multiples ) {
columnSpans[ i ] = multiplesSpans;
} else {
columnSpans[ i ] = remainderSpans;
}
}

return {
minimumColumnCount,
columnSpans,
};
}

function GalleryEdit( props ) {
const {
setAttributes,
Expand All @@ -88,8 +134,15 @@ function GalleryEdit( props ) {
onFocus,
} = props;

const { columns, imageCrop, randomOrder, linkTarget, linkTo, sizeSlug } =
attributes;
const {
columns,
imageCrop,
randomOrder,
linkTarget,
linkTo,
sizeSlug,
layout,
} = attributes;

const {
__unstableMarkNextChangeAsNotPersistent,
Expand Down Expand Up @@ -137,17 +190,60 @@ function GalleryEdit( props ) {
[ clientId ]
);

const images = useMemo(
() =>
innerBlockImages?.map( ( block ) => ( {
const { minimumColumnCount, columnSpans } = getColumnSpans(
columns,
innerBlockImages.length
);

const images = useMemo( () => {
return innerBlockImages?.map( ( block, index ) => {
const newAttributes = {
...block.attributes,
style: {
...block.attributes?.style,
layout: {
...block.attributes?.style?.layout,
columnSpan: columnSpans[ index ],
},
},
};
return {
clientId: block.clientId,
id: block.attributes.id,
url: block.attributes.url,
attributes: block.attributes,
attributes: newAttributes,
fromSavedContent: Boolean( block.originalContent ),
} ) ),
[ innerBlockImages ]
);
};
} );
}, [ innerBlockImages, columns ] );

/* Set the minimumColumnCount attribute to the parent gallery block
* and update the image attributes.
*/
useEffect( () => {
if ( minimumColumnCount !== layout?.columnCount ) {
__unstableMarkNextChangeAsNotPersistent();
setAttributes( {
layout: {
...layout,
type: 'grid',
columnCount: minimumColumnCount || columns,
},
} );
images?.forEach( ( image ) => {
// Update the image attributes without creating new undo levels.
__unstableMarkNextChangeAsNotPersistent();
updateBlockAttributes( image.clientId, {
style: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's a bit off topic from the stated intention of the PR, but making a note as it affects the testing experience.

I'm not sure if it's here, but some image styles are being stripped

So if I add styles to each of the images, e.g., borders those attributes being filtered out after saving. Also affects galleries created in trunk.

Trunk This PR
Screenshot 2024-03-21 at 1 41 48 pm Screenshot 2024-03-21 at 1 42 37 pm

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, probably there, thanks for spotting it!

layout: {
columnSpan:
image.attributes?.style?.layout?.columnSpan,
},
},
} );
} );
}
}, [ minimumColumnCount, columns ] );

const imageData = useGetMedia( innerBlockImages );

Expand Down Expand Up @@ -218,8 +314,8 @@ function GalleryEdit( props ) {
...newLinkTarget,
className: newClassName,
sizeSlug,
caption: imageAttributes.caption || image.caption?.raw,
alt: imageAttributes.alt || image.alt_text,
caption: imageAttributes.caption || image?.caption?.raw,
alt: imageAttributes.alt || image?.alt_text,
};
}

Expand Down Expand Up @@ -619,7 +715,6 @@ function GalleryEdit( props ) {
<Gallery
{ ...props }
isContentLocked={ isContentLocked }
images={ images }
mediaPlaceholder={
! hasImages || Platform.isNative
? mediaPlaceholder
Expand Down
6 changes: 6 additions & 0 deletions packages/block-library/src/gallery/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@
}
}

.wp-block-gallery.is-layout-grid {
> .block-editor-media-placeholder {
grid-column: 1 / -1;
}
}

/**
* Gallery inspector controls settings.
*/
Expand Down
10 changes: 5 additions & 5 deletions packages/block-library/src/gallery/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ figure.wp-block-gallery.has-nested-images {
// Need bogus :not(#individual-image) to override long :not()
// specificity chain on default image block on front end.
figure.wp-block-image:not(#individual-image) {
width: calc(50% - (var(--wp--style--unstable-gallery-gap, #{$grid-unit-20}) / 2));
// width: calc(50% - (var(--wp--style--unstable-gallery-gap, #{$grid-unit-20}) / 2));
margin: 0;
}

Expand Down Expand Up @@ -128,24 +128,24 @@ figure.wp-block-gallery.has-nested-images {
@include break-small {
@for $i from 3 through 8 {
&.columns-#{ $i } figure.wp-block-image:not(#individual-image) {
width: calc(#{math.div(100%, $i)} - (var(--wp--style--unstable-gallery-gap, #{$grid-unit-20}) * #{math.div($i - 1, $i)}));
// width: calc(#{math.div(100%, $i)} - (var(--wp--style--unstable-gallery-gap, #{$grid-unit-20}) * #{math.div($i - 1, $i)}));

}
}
// If number of columns not explicitly set default to 3 columns if 3 or more images.
&.columns-default {
figure.wp-block-image:not(#individual-image) {

width: calc(33.33% - (var(--wp--style--unstable-gallery-gap, 16px) * #{math.div(2, 3)}));
// width: calc(33.33% - (var(--wp--style--unstable-gallery-gap, 16px) * #{math.div(2, 3)}));
}
// If only 2 child images use 2 columns.
figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2),
figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2) ~ figure.wp-block-image:not(#individual-image) {
width: calc(50% - (var(--wp--style--unstable-gallery-gap, 16px) * 0.5));
// width: calc(50% - (var(--wp--style--unstable-gallery-gap, 16px) * 0.5));
}
// For a single image set to 100%.
figure.wp-block-image:not(#individual-image):first-child:nth-last-child(1) {
width: 100%;
// width: 100%;
}
}
}
Expand Down
Loading