From 7c3ec88de3bfee89022ba48eab7afeaa71b65c34 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Mon, 13 Mar 2023 15:57:11 +1100 Subject: [PATCH 01/11] Try adding a grid layout type. --- lib/block-supports/layout.php | 32 +++++ lib/class-wp-theme-json-gutenberg.php | 3 +- lib/experimental/kses.php | 19 +++ lib/theme.json | 15 +++ packages/block-editor/src/layouts/grid.js | 110 ++++++++++++++++++ packages/block-editor/src/layouts/index.js | 3 +- .../block-library/src/group/variations.js | 12 +- 7 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 packages/block-editor/src/layouts/grid.js diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 70029166ce658c..d3f902486bda1a 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -280,6 +280,38 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support ); } } + } elseif ( 'grid' === $layout_type ) { + $minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem'; + + // Workaround because of course core wouldn't support doing anything actually useful with grid. + $layout_styles[] = array( + 'selector' => $selector, + 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(' . $minimum_column_width . ', 1fr))' ), + ); + + if ( $has_block_gap_support && isset( $gap_value ) ) { + $combined_gap_value = ''; + $gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' ); + + foreach ( $gap_sides as $gap_side ) { + $process_value = is_string( $gap_value ) ? $gap_value : _wp_array_get( $gap_value, array( $gap_side ), $fallback_gap_value ); + // Get spacing CSS variable from preset value if provided. + if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) { + $index_to_splice = strrpos( $process_value, '|' ) + 1; + $slug = _wp_to_kebab_case( substr( $process_value, $index_to_splice ) ); + $process_value = "var(--wp--preset--spacing--$slug)"; + } + $combined_gap_value .= "$process_value "; + } + $gap_value = trim( $combined_gap_value ); + + if ( null !== $gap_value && ! $should_skip_gap_serialization ) { + $layout_styles[] = array( + 'selector' => $selector, + 'declarations' => array( 'gap' => $gap_value ), + ); + } + } } if ( ! empty( $layout_styles ) ) { diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 5bd06274e6efd2..1c1b1b5a4b1d66 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -1341,8 +1341,7 @@ protected function get_layout_styles( $block_metadata ) { $base_style_rules = _wp_array_get( $layout_definition, array( 'baseStyles' ), array() ); if ( - ! empty( $class_name ) && - ! empty( $base_style_rules ) + ! empty( $class_name ) ) { // Output display mode. This requires special handling as `display` is not exposed in `safe_style_css_filter`. if ( diff --git a/lib/experimental/kses.php b/lib/experimental/kses.php index a79ef5dbdce42a..629ed3da4d766c 100644 --- a/lib/experimental/kses.php +++ b/lib/experimental/kses.php @@ -87,3 +87,22 @@ function allow_filter_in_styles( $allow_css, $css_test_string ) { } add_filter( 'safecss_filter_attr_allow_css', 'allow_filter_in_styles', 10, 2 ); + +/** + * Mark CSS safe if it contains grid functions + * + * This function should not be backported to core. + * + * @param bool $allow_css Whether the CSS is allowed. + * @param string $css_test_string The CSS to test. + */ +function allow_grid_functions_in_styles( $allow_css, $css_test_string ) { + if ( preg_match( + '/^grid-template-columns:\s*repeat\(auto-fill,[0-9,a-z\s\(\)]*\)$/', + $css_test_string + ) ) { + return true; + } + return $allow_css; +} +add_filter( 'safecss_filter_attr_allow_css', 'allow_grid_functions_in_styles', 10, 2 ); diff --git a/lib/theme.json b/lib/theme.json index fa3a872518adc7..26efc50e3a609f 100644 --- a/lib/theme.json +++ b/lib/theme.json @@ -352,6 +352,21 @@ } } ] + }, + "grid": { + "name": "grid", + "slug": "grid", + "className": "is-layout-grid", + "displayMode": "grid", + "baseStyles": [], + "spacingStyles": [ + { + "selector": "", + "rules": { + "gap": null + } + } + ] } } }, diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js new file mode 100644 index 00000000000000..9b09a61d2a7fc8 --- /dev/null +++ b/packages/block-editor/src/layouts/grid.js @@ -0,0 +1,110 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +import { + Flex, + FlexItem, + __experimentalUnitControl as UnitControl, +} from '@wordpress/components'; + +/** + * Internal dependencies + */ +import { appendSelectors, getBlockGapCSS } from './utils'; +import { getGapCSSValue } from '../hooks/gap'; +import { shouldSkipSerialization } from '../hooks/utils'; + +export default { + name: 'grid', + label: __( 'Grid' ), + inspectorControls: function GridLayoutInspectorControls( { + layout = {}, + onChange, + } ) { + return ( + <> + + + + + + + ); + }, + toolBarControls: function DefaultLayoutToolbarControls() { + return null; + }, + getLayoutStyle: function getLayoutStyle( { + selector, + layout, + style, + blockName, + hasBlockGapSupport, + layoutDefinitions, + } ) { + const { minimumColumnWidth = '12rem' } = layout; + + // If a block's block.json skips serialization for spacing or spacing.blockGap, + // don't apply the user-defined value to the styles. + const blockGapValue = + style?.spacing?.blockGap && + ! shouldSkipSerialization( blockName, 'spacing', 'blockGap' ) + ? getGapCSSValue( style?.spacing?.blockGap, '0.5em' ) + : undefined; + + let output = ''; + const rules = []; + + if ( minimumColumnWidth ) { + rules.push( + `grid-template-columns: repeat(auto-fill, minmax(${ minimumColumnWidth }, 1fr))` + ); + } + + if ( rules.length ) { + output = `${ appendSelectors( selector ) } { + ${ rules.join( '; ' ) }; + }`; + } + + // Output blockGap styles based on rules contained in layout definitions in theme.json. + if ( hasBlockGapSupport && blockGapValue ) { + output += getBlockGapCSS( + selector, + layoutDefinitions, + 'grid', + blockGapValue + ); + } + return output; + }, + getOrientation() { + return null; + }, + getAlignments() { + return []; + }, +}; + +// Enables setting minimum width of grid items. +function GridLayoutMinimumWidthControl( { layout, onChange } ) { + const { minimumColumnWidth = '20rem' } = layout; + + return ( + { + onChange( { + ...layout, + minimumColumnWidth: value, + } ); + } } + value={ minimumColumnWidth } + /> + ); +} diff --git a/packages/block-editor/src/layouts/index.js b/packages/block-editor/src/layouts/index.js index 4ec1ff6f331911..1d30ac3ad36833 100644 --- a/packages/block-editor/src/layouts/index.js +++ b/packages/block-editor/src/layouts/index.js @@ -4,8 +4,9 @@ import flex from './flex'; import flow from './flow'; import constrained from './constrained'; +import grid from './grid'; -const layoutTypes = [ flow, flex, constrained ]; +const layoutTypes = [ flow, flex, constrained, grid ]; /** * Retrieves a layout type by name. diff --git a/packages/block-library/src/group/variations.js b/packages/block-library/src/group/variations.js index 2b64d794dd4cc2..8589b7f73fed43 100644 --- a/packages/block-library/src/group/variations.js +++ b/packages/block-library/src/group/variations.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { __, _x } from '@wordpress/i18n'; -import { group, row, stack } from '@wordpress/icons'; +import { group, row, stack, grid } from '@wordpress/icons'; const variations = [ { @@ -42,6 +42,16 @@ const variations = [ blockAttributes.layout?.orientation === 'vertical', icon: stack, }, + { + name: 'group-grid', + title: __( 'Grid' ), + description: __( 'Arrange blocks in a grid.' ), + attributes: { layout: { type: 'grid' } }, + scope: [ 'block', 'inserter', 'transform' ], + isActive: ( blockAttributes ) => + blockAttributes.layout?.type === 'grid', + icon: grid, + }, ]; export default variations; From 439499eacc4408052aa56ebd9bf4b0a6e8056626 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 14 Mar 2023 12:09:56 +1100 Subject: [PATCH 02/11] Add static column number option --- lib/block-supports/layout.php | 22 +++++-- lib/experimental/kses.php | 2 +- packages/block-editor/src/layouts/grid.js | 74 +++++++++++++++++++++-- 3 files changed, 87 insertions(+), 11 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index d3f902486bda1a..c0a8c5a5656cfc 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -281,13 +281,23 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support } } } elseif ( 'grid' === $layout_type ) { - $minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem'; - // Workaround because of course core wouldn't support doing anything actually useful with grid. - $layout_styles[] = array( - 'selector' => $selector, - 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(' . $minimum_column_width . ', 1fr))' ), - ); + if ( $layout['isResponsive'] ) { + $minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem'; + + $layout_styles[] = array( + 'selector' => $selector, + 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(' . $minimum_column_width . ', 1fr))' ), + ); + + } else { + $number_of_columns = ! empty( $layout['numberOfColumns'] ) ? $layout['numberOfColumns'] : 3; + + $layout_styles[] = array( + 'selector' => $selector, + 'declarations' => array( 'grid-template-columns' => 'repeat(' . $number_of_columns . ', 1fr)' ), + ); + } if ( $has_block_gap_support && isset( $gap_value ) ) { $combined_gap_value = ''; diff --git a/lib/experimental/kses.php b/lib/experimental/kses.php index 629ed3da4d766c..1138aa67933ef0 100644 --- a/lib/experimental/kses.php +++ b/lib/experimental/kses.php @@ -98,7 +98,7 @@ function allow_filter_in_styles( $allow_css, $css_test_string ) { */ function allow_grid_functions_in_styles( $allow_css, $css_test_string ) { if ( preg_match( - '/^grid-template-columns:\s*repeat\(auto-fill,[0-9,a-z\s\(\)]*\)$/', + '/^grid-template-columns:\s*repeat\([0-9,a-z-\s\(\)]*\)$/', $css_test_string ) ) { return true; diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index 9b09a61d2a7fc8..ee647be39c7853 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -6,6 +6,8 @@ import { __ } from '@wordpress/i18n'; import { Flex, FlexItem, + RangeControl, + ToggleControl, __experimentalUnitControl as UnitControl, } from '@wordpress/components'; @@ -23,15 +25,33 @@ export default { layout = {}, onChange, } ) { + const { isResponsive = true } = layout; + return ( <> - + - + { isResponsive && ( + + + + ) } + { ! isResponsive && ( + + + + ) } ); @@ -47,7 +67,11 @@ export default { hasBlockGapSupport, layoutDefinitions, } ) { - const { minimumColumnWidth = '12rem' } = layout; + const { + isResponsive = true, + minimumColumnWidth = '12rem', + numberOfColumns = 3, + } = layout; // If a block's block.json skips serialization for spacing or spacing.blockGap, // don't apply the user-defined value to the styles. @@ -60,10 +84,14 @@ export default { let output = ''; const rules = []; - if ( minimumColumnWidth ) { + if ( isResponsive && minimumColumnWidth ) { rules.push( `grid-template-columns: repeat(auto-fill, minmax(${ minimumColumnWidth }, 1fr))` ); + } else if ( numberOfColumns ) { + rules.push( + `grid-template-columns: repeat(${ numberOfColumns }, 1fr)` + ); } if ( rules.length ) { @@ -108,3 +136,41 @@ function GridLayoutMinimumWidthControl( { layout, onChange } ) { /> ); } + +// Enables setting number of grid columns +function GridLayoutColumnsControl( { layout, onChange } ) { + const { numberOfColumns = 3 } = layout; + + return ( + { + onChange( { + ...layout, + numberOfColumns: value, + } ); + } } + min={ 1 } + max={ 12 } + /> + ); +} + +// Toggle between responsive and fixed column grid. +function GridLayoutResponsiveControl( { layout, onChange } ) { + const { isResponsive = true } = layout; + + return ( + { + onChange( { + ...layout, + isResponsive: ! isResponsive, + } ); + } } + /> + ); +} From afa41248f2218864030eafaae9fb878c10485bbf Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 14 Mar 2023 13:52:21 +1100 Subject: [PATCH 03/11] Address feedback and fix Group placeholder --- lib/block-supports/layout.php | 3 ++- lib/class-wp-theme-json-gutenberg.php | 3 ++- lib/theme.json | 9 ++++++++- packages/block-editor/src/layouts/grid.js | 1 + packages/block-library/src/group/placeholder.js | 14 +++++++++++++- 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index c0a8c5a5656cfc..a8b1337a286cde 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -281,8 +281,9 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support } } } elseif ( 'grid' === $layout_type ) { + $is_responsive = array_key_exists( 'isResponsive', $layout ) ? $layout['isResponsive'] : true; - if ( $layout['isResponsive'] ) { + if ( $is_responsive ) { $minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem'; $layout_styles[] = array( diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 1c1b1b5a4b1d66..4a6f1430b38437 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -1341,7 +1341,8 @@ protected function get_layout_styles( $block_metadata ) { $base_style_rules = _wp_array_get( $layout_definition, array( 'baseStyles' ), array() ); if ( - ! empty( $class_name ) + ! empty( $class_name ) && + is_array( $base_style_rules ) ) { // Output display mode. This requires special handling as `display` is not exposed in `safe_style_css_filter`. if ( diff --git a/lib/theme.json b/lib/theme.json index 26efc50e3a609f..af23346dd4649d 100644 --- a/lib/theme.json +++ b/lib/theme.json @@ -358,7 +358,14 @@ "slug": "grid", "className": "is-layout-grid", "displayMode": "grid", - "baseStyles": [], + "baseStyles": [ + { + "selector": " > *", + "rules": { + "margin": "0" + } + } + ], "spacingStyles": [ { "selector": "", diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index ee647be39c7853..70773910ceb85b 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -126,6 +126,7 @@ function GridLayoutMinimumWidthControl( { layout, onChange } ) { return ( { onChange( { ...layout, diff --git a/packages/block-library/src/group/placeholder.js b/packages/block-library/src/group/placeholder.js index daf535df8bf607..16a99a9287338d 100644 --- a/packages/block-library/src/group/placeholder.js +++ b/packages/block-library/src/group/placeholder.js @@ -47,6 +47,17 @@ const getGroupPlaceholderIcons = ( name = 'group' ) => { ), + 'group-grid': ( + + + + + ), }; return icons?.[ name ]; }; @@ -85,7 +96,8 @@ export function useShouldShowPlaceHolder( { ! fontSize && ! textColor && ! style && - usedLayoutType !== 'flex' + usedLayoutType !== 'flex' && + usedLayoutType !== 'grid' ); useEffect( () => { From 99a52f5a603a423859db72a478233bde8441578e Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Thu, 16 Mar 2023 13:51:58 +1100 Subject: [PATCH 04/11] Revert non-responsive option --- lib/block-supports/layout.php | 12 ---- packages/block-editor/src/layouts/grid.js | 72 +---------------------- 2 files changed, 3 insertions(+), 81 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index a8b1337a286cde..f7866b9c7d5b7a 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -281,9 +281,6 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support } } } elseif ( 'grid' === $layout_type ) { - $is_responsive = array_key_exists( 'isResponsive', $layout ) ? $layout['isResponsive'] : true; - - if ( $is_responsive ) { $minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem'; $layout_styles[] = array( @@ -291,15 +288,6 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(' . $minimum_column_width . ', 1fr))' ), ); - } else { - $number_of_columns = ! empty( $layout['numberOfColumns'] ) ? $layout['numberOfColumns'] : 3; - - $layout_styles[] = array( - 'selector' => $selector, - 'declarations' => array( 'grid-template-columns' => 'repeat(' . $number_of_columns . ', 1fr)' ), - ); - } - if ( $has_block_gap_support && isset( $gap_value ) ) { $combined_gap_value = ''; $gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' ); diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index 70773910ceb85b..eb86c026162021 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -6,8 +6,6 @@ import { __ } from '@wordpress/i18n'; import { Flex, FlexItem, - RangeControl, - ToggleControl, __experimentalUnitControl as UnitControl, } from '@wordpress/components'; @@ -25,33 +23,15 @@ export default { layout = {}, onChange, } ) { - const { isResponsive = true } = layout; - return ( <> - - { isResponsive && ( - - - - ) } - { ! isResponsive && ( - - - - ) } ); @@ -67,11 +47,7 @@ export default { hasBlockGapSupport, layoutDefinitions, } ) { - const { - isResponsive = true, - minimumColumnWidth = '12rem', - numberOfColumns = 3, - } = layout; + const { minimumColumnWidth = '12rem' } = layout; // If a block's block.json skips serialization for spacing or spacing.blockGap, // don't apply the user-defined value to the styles. @@ -84,14 +60,10 @@ export default { let output = ''; const rules = []; - if ( isResponsive && minimumColumnWidth ) { + if ( minimumColumnWidth ) { rules.push( `grid-template-columns: repeat(auto-fill, minmax(${ minimumColumnWidth }, 1fr))` ); - } else if ( numberOfColumns ) { - rules.push( - `grid-template-columns: repeat(${ numberOfColumns }, 1fr)` - ); } if ( rules.length ) { @@ -137,41 +109,3 @@ function GridLayoutMinimumWidthControl( { layout, onChange } ) { /> ); } - -// Enables setting number of grid columns -function GridLayoutColumnsControl( { layout, onChange } ) { - const { numberOfColumns = 3 } = layout; - - return ( - { - onChange( { - ...layout, - numberOfColumns: value, - } ); - } } - min={ 1 } - max={ 12 } - /> - ); -} - -// Toggle between responsive and fixed column grid. -function GridLayoutResponsiveControl( { layout, onChange } ) { - const { isResponsive = true } = layout; - - return ( - { - onChange( { - ...layout, - isResponsive: ! isResponsive, - } ); - } } - /> - ); -} From b338b7342e68a29c66d68c6bcec50cc71a591246 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Mon, 20 Mar 2023 16:19:04 +1100 Subject: [PATCH 05/11] Add range control --- packages/block-editor/src/layouts/grid.js | 98 ++++++++++++++++++----- 1 file changed, 76 insertions(+), 22 deletions(-) diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index eb86c026162021..6d48e0ff4b24e2 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -6,7 +6,9 @@ import { __ } from '@wordpress/i18n'; import { Flex, FlexItem, + RangeControl, __experimentalUnitControl as UnitControl, + __experimentalParseQuantityAndUnitFromRawValue as parseQuantityAndUnitFromRawValue, } from '@wordpress/components'; /** @@ -16,6 +18,15 @@ import { appendSelectors, getBlockGapCSS } from './utils'; import { getGapCSSValue } from '../hooks/gap'; import { shouldSkipSerialization } from '../hooks/utils'; +const RANGE_CONTROL_MAX_VALUES = { + px: 600, + '%': 100, + vw: 100, + vh: 100, + em: 38, + rem: 38, +}; + export default { name: 'grid', label: __( 'Grid' ), @@ -24,16 +35,10 @@ export default { onChange, } ) { return ( - <> - - - - - - + ); }, toolBarControls: function DefaultLayoutToolbarControls() { @@ -93,19 +98,68 @@ export default { // Enables setting minimum width of grid items. function GridLayoutMinimumWidthControl( { layout, onChange } ) { - const { minimumColumnWidth = '20rem' } = layout; + const { minimumColumnWidth: value = '12rem' } = layout; + const [ quantity, unit ] = parseQuantityAndUnitFromRawValue( value ); + + const handleSliderChange = ( next ) => { + onChange( { + ...layout, + minimumColumnWidth: [ next, unit ].join( '' ), + } ); + }; + + // Mostly copied from HeightControl. + const handleUnitChange = ( newUnit ) => { + // Attempt to smooth over differences between currentUnit and newUnit. + // This should slightly improve the experience of switching between unit types. + let newValue; + + if ( [ 'em', 'rem' ].includes( newUnit ) && unit === 'px' ) { + // Convert pixel value to an approximate of the new unit, assuming a root size of 16px. + newValue = ( quantity / 16 ).toFixed( 2 ) + newUnit; + } else if ( [ 'em', 'rem' ].includes( unit ) && newUnit === 'px' ) { + // Convert to pixel value assuming a root size of 16px. + newValue = Math.round( quantity * 16 ) + newUnit; + } else if ( + [ 'vh', 'vw', '%' ].includes( newUnit ) && + quantity > 100 + ) { + // When converting to `vh`, `vw`, or `%` units, cap the new value at 100. + newValue = 100 + newUnit; + } + + onChange( { + ...layout, + minimumColumnWidth: newValue, + } ); + }; return ( - { - onChange( { - ...layout, - minimumColumnWidth: value, - } ); - } } - value={ minimumColumnWidth } - /> + + + { + onChange( { + ...layout, + minimumColumnWidth: newValue, + } ); + } } + onUnitChange={ handleUnitChange } + value={ value } + min={ 0 } + /> + + + + + ); } From 7bb10f9c380aa408baaa35f33b74b2bfa07896a3 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 21 Mar 2023 14:04:42 +1100 Subject: [PATCH 06/11] Wrap controls in fieldset and add legend. --- packages/block-editor/src/layouts/grid.js | 57 ++++++++++++----------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index 6d48e0ff4b24e2..e332aabc574ae9 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -4,6 +4,7 @@ import { __ } from '@wordpress/i18n'; import { + BaseControl, Flex, FlexItem, RangeControl, @@ -135,31 +136,35 @@ function GridLayoutMinimumWidthControl( { layout, onChange } ) { }; return ( - - - { - onChange( { - ...layout, - minimumColumnWidth: newValue, - } ); - } } - onUnitChange={ handleUnitChange } - value={ value } - min={ 0 } - /> - - - - - +
+ + { __( 'Minimum column width' ) } + + + + { + onChange( { + ...layout, + minimumColumnWidth: newValue, + } ); + } } + onUnitChange={ handleUnitChange } + value={ value } + min={ 0 } + /> + + + + + +
); } From 52bfcc7ee85e42cfe192a6957f5e4a595d15147f Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 21 Mar 2023 14:42:49 +1100 Subject: [PATCH 07/11] Fix responsivity of min size --- lib/block-supports/layout.php | 2 +- packages/block-editor/src/layouts/grid.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index f7866b9c7d5b7a..cc43254f30565a 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -285,7 +285,7 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support $layout_styles[] = array( 'selector' => $selector, - 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(' . $minimum_column_width . ', 1fr))' ), + 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(min(' . $minimum_column_width . ', 100%), 1fr))' ), ); if ( $has_block_gap_support && isset( $gap_value ) ) { diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index e332aabc574ae9..33c86628808f08 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -68,7 +68,7 @@ export default { if ( minimumColumnWidth ) { rules.push( - `grid-template-columns: repeat(auto-fill, minmax(${ minimumColumnWidth }, 1fr))` + `grid-template-columns: repeat(auto-fill, minmax(min(${ minimumColumnWidth }, 100%), 1fr))` ); } From 04778c8f6b3882e57554a3058caa0e3a240747b3 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 22 Mar 2023 14:53:21 +1100 Subject: [PATCH 08/11] Grid child movers should be horizontal. --- packages/block-editor/src/layouts/grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index 33c86628808f08..d9a2c9dfc742e6 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -90,7 +90,7 @@ export default { return output; }, getOrientation() { - return null; + return 'horizontal'; }, getAlignments() { return []; From f85a8b583fafc1fd913e8b4302d7c2b597275875 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Wed, 22 Mar 2023 15:53:06 +1100 Subject: [PATCH 09/11] Fix indentation in layout file. --- lib/block-supports/layout.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index cc43254f30565a..e255cf89d32f7c 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -281,12 +281,12 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support } } } elseif ( 'grid' === $layout_type ) { - $minimum_column_width = ! empty( $layout['minimumColumnWidth'] ) ? $layout['minimumColumnWidth'] : '12rem'; + $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))' ), - ); + $layout_styles[] = array( + 'selector' => $selector, + 'declarations' => array( 'grid-template-columns' => 'repeat(auto-fill, minmax(min(' . $minimum_column_width . ', 100%), 1fr))' ), + ); if ( $has_block_gap_support && isset( $gap_value ) ) { $combined_gap_value = ''; From 470fcf309182a82e4a7c8fa3a661210e71e535ce Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Thu, 23 Mar 2023 15:48:03 +1100 Subject: [PATCH 10/11] Adjust gap between controls --- packages/block-editor/src/layouts/grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index d9a2c9dfc742e6..1e7e554c60fae1 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -140,7 +140,7 @@ function GridLayoutMinimumWidthControl( { layout, onChange } ) { { __( 'Minimum column width' ) } - + Date: Thu, 23 Mar 2023 16:17:32 +1100 Subject: [PATCH 11/11] Add a test for grid style output. --- packages/block-editor/src/layouts/grid.js | 8 ++++--- .../block-editor/src/layouts/test/grid.js | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 packages/block-editor/src/layouts/test/grid.js diff --git a/packages/block-editor/src/layouts/grid.js b/packages/block-editor/src/layouts/grid.js index 1e7e554c60fae1..69347123fd4213 100644 --- a/packages/block-editor/src/layouts/grid.js +++ b/packages/block-editor/src/layouts/grid.js @@ -73,9 +73,11 @@ export default { } if ( rules.length ) { - output = `${ appendSelectors( selector ) } { - ${ rules.join( '; ' ) }; - }`; + // Reason to disable: the extra line breaks added by prettier mess with the unit tests. + // eslint-disable-next-line prettier/prettier + output = `${ appendSelectors( selector ) } { ${ rules.join( + '; ' + ) }; }`; } // Output blockGap styles based on rules contained in layout definitions in theme.json. diff --git a/packages/block-editor/src/layouts/test/grid.js b/packages/block-editor/src/layouts/test/grid.js new file mode 100644 index 00000000000000..634457670f0dfa --- /dev/null +++ b/packages/block-editor/src/layouts/test/grid.js @@ -0,0 +1,21 @@ +/** + * Internal dependencies + */ +import grid from '../grid'; + +describe( 'getLayoutStyle', () => { + it( 'should return a single `grid-template-columns` property if no non-default params are provided', () => { + const expected = `.editor-styles-wrapper .my-container { grid-template-columns: repeat(auto-fill, minmax(min(12rem, 100%), 1fr)); }`; + + const result = grid.getLayoutStyle( { + selector: '.my-container', + layout: {}, + style: {}, + blockName: 'test-block', + hasBlockGapSupport: false, + layoutDefinitions: undefined, + } ); + + expect( result ).toBe( expected ); + } ); +} );