From 351b6c88bb59fddf0caf2f27694f33bd5c52205c Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Thu, 15 Feb 2024 18:16:52 +1100 Subject: [PATCH] Refactor responsive logic for grid column spans. --- lib/block-supports/layout.php | 28 +++++++++++++++++-- .../components/child-layout-control/index.js | 16 +++-------- .../global-styles/dimensions-panel.js | 14 +++++----- .../block-editor/src/hooks/layout-child.js | 17 ++++++----- 4 files changed, 46 insertions(+), 29 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 3c7117ca26a1f5..48cb206fd7894e 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -596,13 +596,16 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { /** * If columnSpan is set, and the parent grid is responsive, i.e. if it has a minimumColumnWidth set, - * the columnSpan should be removed on small grids. + * the columnSpan should be removed on small grids. If there's a minimumColumnWidth, the grid is responsive. + * But if the minimumColumnWidth value wasn't changed, it won't be set. In that case, if columnCount doesn't + * exist, we can assume that the grid is responsive. */ - if ( isset( $block['attrs']['style']['layout']['columnSpan'] ) && isset( $block['attrs']['style']['layout']['parentColumnWidth'] ) ) { + if ( isset( $block['attrs']['style']['layout']['columnSpan'] ) && ( isset( $block['parentLayout']['minimumColumnWidth'] ) || ! isset( $block['parentLayout']['columnCount'] ) ) ) { $column_span_number = floatval( $block['attrs']['style']['layout']['columnSpan'] ); - $parent_column_width = $block['attrs']['style']['layout']['parentColumnWidth']; + $parent_column_width = isset( $block['parentLayout']['minimumColumnWidth'] ) ? $block['parentLayout']['minimumColumnWidth'] : '12rem'; $parent_column_value = floatval( $parent_column_width ); $parent_column_unit = explode( $parent_column_value, $parent_column_width ); + /** * If there is no unit, the width has somehow been mangled so we reset both unit and value * to defaults. @@ -887,6 +890,25 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { return $processor->get_updated_html(); } +/** + * Add a `render_block_data` filter to fetch the parent block layout data. + */ +add_filter( + 'render_block_data', + function ( $parsed_block, $source_block, $parent_block ) { + /** + * Check if the parent block exists and if it has a layout attribute. + * If it does, add the parent layout to the parsed block. + */ + if ( $parent_block && isset( $parent_block->parsed_block['attrs']['layout'] ) ) { + $parsed_block['parentLayout'] = $parent_block->parsed_block['attrs']['layout']; + } + return $parsed_block; + }, + 10, + 3 +); + // Register the block support. (overrides core one). WP_Block_Supports::get_instance()->register( 'layout', diff --git a/packages/block-editor/src/components/child-layout-control/index.js b/packages/block-editor/src/components/child-layout-control/index.js index 59ec27dcfbc6f9..310d9cd2a3f155 100644 --- a/packages/block-editor/src/components/child-layout-control/index.js +++ b/packages/block-editor/src/components/child-layout-control/index.js @@ -42,16 +42,10 @@ export default function ChildLayoutControl( { } ) { const { selfStretch, flexSize, columnSpan, rowSpan } = childLayout; const { - type: parentLayoutType, - minimumColumnWidth = '12rem', - columnCount, - } = parentLayout; - - /** - * If columnCount is set, the parentColumnwidth isn't needed because - * the grid has a fixed number of columns with responsive widths. - */ - const parentColumnWidth = columnCount ? null : minimumColumnWidth; + type: parentType, + default: { type: defaultParentType = 'default' } = {}, + } = parentLayout ?? {}; + const parentLayoutType = parentType || defaultParentType; useEffect( () => { if ( selfStretch === 'fixed' && ! flexSize ) { @@ -122,7 +116,6 @@ export default function ChildLayoutControl( { onChange( { rowSpan, columnSpan: value, - parentColumnWidth, } ); } } value={ columnSpan } @@ -135,7 +128,6 @@ export default function ChildLayoutControl( { onChange={ ( value ) => { onChange( { columnSpan, - parentColumnWidth, rowSpan: value, } ); } } diff --git a/packages/block-editor/src/components/global-styles/dimensions-panel.js b/packages/block-editor/src/components/global-styles/dimensions-panel.js index c3b60e8f65d607..1386df0dfe2894 100644 --- a/packages/block-editor/src/components/global-styles/dimensions-panel.js +++ b/packages/block-editor/src/components/global-styles/dimensions-panel.js @@ -97,7 +97,6 @@ function useHasChildLayout( settings ) { defaultParentLayoutType === 'grid' || parentLayoutType === 'grid' ) && allowSizingOnChildren; - return !! settings?.layout && support; } @@ -397,13 +396,16 @@ export default function DimensionsPanel( { // Child Layout const showChildLayoutControl = useHasChildLayout( settings ); const childLayout = inheritedValue?.layout; - const { selfStretch } = childLayout ?? {}; const { orientation = 'horizontal' } = settings?.parentLayout ?? {}; + const { + type: parentType, + default: { type: defaultParentType = 'default' } = {}, + } = settings?.parentLayout ?? {}; + const parentLayoutType = parentType || defaultParentType; const flexResetLabel = orientation === 'horizontal' ? __( 'Width' ) : __( 'Height' ); - const childLayoutResetLabel = selfStretch - ? flexResetLabel - : __( 'Grid spans' ); + const childLayoutResetLabel = + parentLayoutType === 'flex' ? flexResetLabel : __( 'Grid spans' ); const setChildLayout = ( newChildLayout ) => { onChange( { ...value, @@ -418,7 +420,6 @@ export default function DimensionsPanel( { flexSize: undefined, columnSpan: undefined, rowSpan: undefined, - parentColumnWidth: undefined, } ); }; const hasChildLayoutValue = () => !! value?.layout; @@ -434,7 +435,6 @@ export default function DimensionsPanel( { flexSize: undefined, columnSpan: undefined, rowSpan: undefined, - parentColumnWidth: undefined, } ), spacing: { ...previousValue?.spacing, diff --git a/packages/block-editor/src/hooks/layout-child.js b/packages/block-editor/src/hooks/layout-child.js index d3219d8dfc5636..a9a6ff4db0f4ab 100644 --- a/packages/block-editor/src/hooks/layout-child.js +++ b/packages/block-editor/src/hooks/layout-child.js @@ -9,14 +9,16 @@ import { useSelect } from '@wordpress/data'; */ import { store as blockEditorStore } from '../store'; import { useStyleOverride } from './utils'; +import { useLayout } from '../components/block-list/layout'; function useBlockPropsChildLayoutStyles( { style } ) { const shouldRenderChildLayoutStyles = useSelect( ( select ) => { return ! select( blockEditorStore ).getSettings().disableLayoutStyles; } ); const layout = style?.layout ?? {}; - const { selfStretch, flexSize, columnSpan, rowSpan, parentColumnWidth } = - layout; + const { selfStretch, flexSize, columnSpan, rowSpan } = layout; + const parentLayout = useLayout() || {}; + const { columnCount, minimumColumnWidth } = parentLayout; const id = useInstanceId( useBlockPropsChildLayoutStyles ); const selector = `.wp-container-content-${ id }`; @@ -37,13 +39,14 @@ function useBlockPropsChildLayoutStyles( { style } ) { }`; } /** - * If parentColumnWidth is set, the grid is responsive - * so a container query is needed for the span to resize. + * If minimumColumnWidth is set on the parent, or if no + * columnCount is set, the grid is responsive so a + * container query is needed for the span to resize. */ - if ( columnSpan && parentColumnWidth ) { + if ( columnSpan && ( minimumColumnWidth || ! columnCount ) ) { // Calculate the container query value. const columnSpanNumber = parseInt( columnSpan ); - let parentColumnValue = parseFloat( parentColumnWidth ); + let parentColumnValue = parseFloat( minimumColumnWidth ); /** * 12rem is the default minimumColumnWidth value. * If parentColumnValue is not a number, default to 12. @@ -52,7 +55,7 @@ function useBlockPropsChildLayoutStyles( { style } ) { parentColumnValue = 12; } - let parentColumnUnit = parentColumnWidth?.replace( + let parentColumnUnit = minimumColumnWidth?.replace( parentColumnValue, '' );