Skip to content

Commit

Permalink
Try using manualPlacement attribute to set manual grid mode and all…
Browse files Browse the repository at this point in the history
…ow responsive behaviour in both modes. (WordPress#62777)

Co-authored-by: noisysocks <noisysocks@git.wordpress.org>
Co-authored-by: tellthemachines <isabel_brison@git.wordpress.org>
Co-authored-by: andrewserong <andrewserong@git.wordpress.org>
Co-authored-by: jasmussen <joen@git.wordpress.org>
Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
  • Loading branch information
6 people authored and carstingaxion committed Jul 18, 2024
1 parent 3ffbee0 commit c5e8c45
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 99 deletions.
5 changes: 5 additions & 0 deletions backport-changelog/6.7/6910.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
https://github.com/WordPress/wordpress-develop/pull/6910

* https://github.com/WordPress/gutenberg/pull/59483
* https://github.com/WordPress/gutenberg/pull/60652
* https://github.com/WordPress/gutenberg/pull/62777
80 changes: 50 additions & 30 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -466,29 +466,8 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
}
}
} elseif ( 'grid' === $layout_type ) {
if ( ! empty( $layout['columnCount'] ) ) {
$layout_styles[] = array(
'selector' => $selector,
'declarations' => array( 'grid-template-columns' => 'repeat(' . $layout['columnCount'] . ', minmax(0, 1fr))' ),
);
if ( ! empty( $layout['rowCount'] ) ) {
$layout_styles[] = array(
'selector' => $selector,
'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout['rowCount'] . ', minmax(0, 1fr))' ),
);
}
} else {
$minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem';

$layout_styles[] = array(
'selector' => $selector,
'declarations' => array(
'grid-template-columns' => 'repeat(auto-fill, minmax(min(' . $minimum_column_width . ', 100%), 1fr))',
'container-type' => 'inline-size',
),
);
}

// Deal with block gap first so it can be used for responsive computation.
$responsive_gap_value = '1.2rem';
if ( $has_block_gap_support && isset( $gap_value ) ) {
$combined_gap_value = '';
$gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' );
Expand All @@ -506,14 +485,53 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
}
$combined_gap_value .= "$process_value ";
}
$gap_value = trim( $combined_gap_value );
$gap_value = trim( $combined_gap_value );
$responsive_gap_value = $gap_value;
}

if ( null !== $gap_value && ! $should_skip_gap_serialization ) {
if ( ! empty( $layout['columnCount'] ) && ! empty( $layout['minimumColumnWidth'] ) ) {
$max_value = 'max(' . $layout['minimumColumnWidth'] . ', (100% - (' . $responsive_gap_value . ' * (' . $layout['columnCount'] . ' - 1))) /' . $layout['columnCount'] . ')';
$layout_styles[] = array(
'selector' => $selector,
'declarations' => array(
'grid-template-columns' => 'repeat(auto-fill, minmax(' . $max_value . ', 1fr))',
'container-type' => 'inline-size',
),
);
if ( ! empty( $layout['rowCount'] ) ) {
$layout_styles[] = array(
'selector' => $selector,
'declarations' => array( 'gap' => $gap_value ),
'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout['rowCount'] . ', minmax(8px, auto))' ),
);
}
} elseif ( ! empty( $layout['columnCount'] ) ) {
$layout_styles[] = array(
'selector' => $selector,
'declarations' => array( 'grid-template-columns' => 'repeat(' . $layout['columnCount'] . ', minmax(0, 1fr))' ),
);
if ( ! empty( $layout['rowCount'] ) ) {
$layout_styles[] = array(
'selector' => $selector,
'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout['rowCount'] . ', minmax(8px, auto))' ),
);
}
} else {
$minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem';

$layout_styles[] = array(
'selector' => $selector,
'declarations' => array(
'grid-template-columns' => 'repeat(auto-fill, minmax(min(' . $minimum_column_width . ', 100%), 1fr))',
'container-type' => 'inline-size',
),
);
}

if ( $has_block_gap_support && null !== $gap_value && ! $should_skip_gap_serialization ) {
$layout_styles[] = array(
'selector' => $selector,
'declarations' => array( 'gap' => $gap_value ),
);
}
}

Expand Down Expand Up @@ -653,17 +671,19 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
* A default gap value is used for this computation because custom gap values may not be
* viable to use in the computation of the container query value.
*/
$default_gap_value = 'px' === $parent_column_unit ? 24 : 1.5;
$container_query_value = $highest_number * $parent_column_value + ( $highest_number - 1 ) * $default_gap_value;
$container_query_value = $container_query_value . $parent_column_unit;
$default_gap_value = 'px' === $parent_column_unit ? 24 : 1.5;
$container_query_value = $highest_number * $parent_column_value + ( $highest_number - 1 ) * $default_gap_value;
$minimum_container_query_value = $parent_column_value * 2 + $default_gap_value - 1;
$container_query_value = max( $container_query_value, $minimum_container_query_value ) . $parent_column_unit;
// If a span is set we want to preserve it as long as possible, otherwise we just reset the value.
$grid_column_value = $column_span ? '1/-1' : 'auto';
$grid_column_value = $column_span && $column_span > 1 ? '1/-1' : 'auto';

$child_layout_styles[] = array(
'rules_group' => "@container (max-width: $container_query_value )",
'selector' => ".$container_content_class",
'declarations' => array(
'grid-column' => $grid_column_value,
'grid-row' => 'auto',
),
);
}
Expand Down
58 changes: 31 additions & 27 deletions packages/block-editor/src/components/grid/use-grid-layout-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ export function useGridLayoutSync( { clientId: gridClientId } ) {
useEffect( () => {
const updates = {};

const { columnCount, rowCount = 2 } = gridLayout;
const isManualGrid = !! columnCount;
const { columnCount, rowCount, isManualPlacement } = gridLayout;
const isManualGrid = !! isManualPlacement;

if ( isManualGrid ) {
const rects = [];
let cellsTaken = 0;

// Respect the position of blocks that already have a columnStart and rowStart value.
for ( const clientId of blockOrder ) {
Expand All @@ -46,7 +45,6 @@ export function useGridLayoutSync( { clientId: gridClientId } ) {
columnSpan = 1,
rowSpan = 1,
} = attributes.style?.layout || {};
cellsTaken += columnSpan * rowSpan;
if ( ! columnStart || ! rowStart ) {
continue;
}
Expand All @@ -60,29 +58,21 @@ export function useGridLayoutSync( { clientId: gridClientId } ) {
);
}

// Ensure there's enough rows to fit all blocks.
const minimumNeededRows = Math.ceil( cellsTaken / columnCount );
if ( rowCount < minimumNeededRows ) {
updates[ gridClientId ] = {
layout: {
...gridLayout,
rowCount: minimumNeededRows,
},
};
}

// When in manual mode, ensure that every block has a columnStart and rowStart value.
for ( const clientId of blockOrder ) {
const attributes = getBlockAttributes( clientId );
const { columnStart, rowStart, columnSpan, rowSpan } =
attributes.style?.layout || {};
const {
columnStart,
rowStart,
columnSpan = 1,
rowSpan = 1,
} = attributes.style?.layout || {};
if ( columnStart && rowStart ) {
continue;
}
const [ newColumnStart, newRowStart ] = getFirstEmptyCell(
rects,
columnCount,
minimumNeededRows,
columnSpan,
rowSpan
);
Expand All @@ -105,6 +95,17 @@ export function useGridLayoutSync( { clientId: gridClientId } ) {
},
};
}

// Ensure there's enough rows to fit all blocks.
const bottomMostRow = Math.max( ...rects.map( ( r ) => r.rowEnd ) );
if ( ! rowCount || rowCount < bottomMostRow ) {
updates[ gridClientId ] = {
layout: {
...gridLayout,
rowCount: bottomMostRow,
},
};
}
} else {
// When in auto mode, remove all of the columnStart and rowStart values.
for ( const clientId of blockOrder ) {
Expand All @@ -121,6 +122,16 @@ export function useGridLayoutSync( { clientId: gridClientId } ) {
};
}
}

// Remove row styles in auto mode
if ( rowCount ) {
updates[ gridClientId ] = {
layout: {
...gridLayout,
rowCount: undefined,
},
};
}
}

if ( Object.keys( updates ).length ) {
Expand All @@ -143,14 +154,8 @@ export function useGridLayoutSync( { clientId: gridClientId } ) {
] );
}

function getFirstEmptyCell(
rects,
columnCount,
rowCount,
columnSpan = 1,
rowSpan = 1
) {
for ( let row = 1; row <= rowCount; row++ ) {
function getFirstEmptyCell( rects, columnCount, columnSpan = 1, rowSpan = 1 ) {
for ( let row = 1; ; row++ ) {
for ( let column = 1; column <= columnCount; column++ ) {
const rect = new GridRect( {
columnStart: column,
Expand All @@ -163,5 +168,4 @@ function getFirstEmptyCell(
}
}
}
return [ 1, 1 ];
}
39 changes: 24 additions & 15 deletions packages/block-editor/src/hooks/layout-child.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ function useBlockPropsChildLayoutStyles( { style } ) {
grid-column: span ${ columnSpan };
}`;
}
if ( rowStart && rowSpan ) {
css += `${ selector } {
grid-row: ${ rowStart } / span ${ rowSpan };
}`;
} else if ( rowStart ) {
css += `${ selector } {
grid-row: ${ rowStart };
}`;
} else if ( rowSpan ) {
css += `${ selector } {
grid-row: span ${ rowSpan };
}`;
}
/**
* If minimumColumnWidth is set on the parent, or if no
* columnCount is set, the grid is responsive so a
Expand Down Expand Up @@ -103,28 +116,24 @@ function useBlockPropsChildLayoutStyles( { style } ) {
const containerQueryValue =
highestNumber * parentColumnValue +
( highestNumber - 1 ) * defaultGapValue;
// For blocks that only span one column, we want to remove any rowStart values as
// the container reduces in size, so that blocks are still arranged in markup order.
const minimumContainerQueryValue =
parentColumnValue * 2 + defaultGapValue - 1;
// If a span is set we want to preserve it as long as possible, otherwise we just reset the value.
const gridColumnValue = columnSpan ? '1/-1' : 'auto';
const gridColumnValue =
columnSpan && columnSpan > 1 ? '1/-1' : 'auto';

css += `@container (max-width: ${ containerQueryValue }${ parentColumnUnit }) {
css += `@container (max-width: ${ Math.max(
containerQueryValue,
minimumContainerQueryValue
) }${ parentColumnUnit }) {
${ selector } {
grid-column: ${ gridColumnValue };
grid-row: auto;
}
}`;
}
if ( rowStart && rowSpan ) {
css += `${ selector } {
grid-row: ${ rowStart } / span ${ rowSpan };
}`;
} else if ( rowStart ) {
css += `${ selector } {
grid-row: ${ rowStart };
}`;
} else if ( rowSpan ) {
css += `${ selector } {
grid-row: span ${ rowSpan };
}`;
}
}

useStyleOverride( { css } );
Expand Down
Loading

0 comments on commit c5e8c45

Please sign in to comment.