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

[WIP] Update Columns block to use CSS Grid, add option to adjust grid gap #32137

Closed
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
1 change: 1 addition & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function gutenberg_reregister_core_block_types() {
'block.php' => 'core/block',
'calendar.php' => 'core/calendar',
'categories.php' => 'core/categories',
'columns.php' => 'core/columns',
'file.php' => 'core/file',
'latest-comments.php' => 'core/latest-comments',
'latest-posts.php' => 'core/latest-posts',
Expand Down
8 changes: 8 additions & 0 deletions packages/block-library/src/columns/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
"description": "Add a block that displays content in multiple columns, then add whatever content blocks you’d like.",
"textdomain": "default",
"attributes": {
"gridGap": {
"type": "number",
"default": 2
},
"gridGapUnit": {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need gridGap and gridGapUnit as two separate properties, or can we consolidate them into a string like we do with the width attribute in the Column block (it also uses UnitControl so very similar problem).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I don't think we do. Separately to this PR we're looking at a generalised gap block support (tracked in #32366), which I think will be better than storing the attributes with the block here.

"type": "string",
"default": "em"
},
"verticalAlignment": {
"type": "string"
}
Expand Down
17 changes: 15 additions & 2 deletions packages/block-library/src/columns/deprecated.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ const migrateCustomColors = ( attributes ) => {
}
return {
...omit( attributes, [ 'customTextColor', 'customBackgroundColor' ] ),
gridGap: 2,
gridGapUnit: 'em',
style,
};
};
Expand Down Expand Up @@ -166,7 +168,14 @@ export default [
createBlock( 'core/column', {}, columnBlocks )
);

return [ omit( attributes, [ 'columns' ] ), migratedInnerBlocks ];
return [
{
...omit( attributes, [ 'columns' ] ),
gridGap: 2,
gridGapUnit: 'em',
},
migratedInnerBlocks,
];
},
save( { attributes } ) {
const { columns } = attributes;
Expand All @@ -186,7 +195,11 @@ export default [
},
},
migrate( attributes, innerBlocks ) {
attributes = omit( attributes, [ 'columns' ] );
attributes = {
...omit( attributes, [ 'columns' ] ),
gridGap: 2,
gridGapUnit: 'em',
};

return [ attributes, innerBlocks ];
},
Expand Down
116 changes: 111 additions & 5 deletions packages/block-library/src/columns/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,26 @@ import { dropRight, get, times } from 'lodash';
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { PanelBody, RangeControl, Notice } from '@wordpress/components';

import {
BaseControl,
Notice,
PanelBody,
RangeControl,
__experimentalUseCustomUnits as useCustomUnits,
} from '@wordpress/components';
import {
InspectorControls,
__experimentalUseInnerBlocksProps as useInnerBlocksProps,
BlockControls,
BlockVerticalAlignmentToolbar,
__experimentalBlockVariationPicker,
useBlockProps,
useSetting,
__experimentalUnitControl as UnitControl,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { useInstanceId } from '@wordpress/compose';
import { useEffect, useState } from '@wordpress/element';
import { withDispatch, useDispatch, useSelect } from '@wordpress/data';
import {
createBlock,
Expand All @@ -31,6 +40,7 @@ import {
*/
import {
hasExplicitPercentColumnWidths,
getColumnWidthsAsGridColumnsValues,
getMappedColumnWidths,
getRedistributedColumnWidths,
toWidthPrecision,
Expand All @@ -47,30 +57,114 @@ import {
*/
const ALLOWED_BLOCKS = [ 'core/column' ];

function GridGapInput( { onChange, onUnitChange, unit = 'px', value = '' } ) {
const [ temporaryInput, setTemporaryInput ] = useState( null );

const instanceId = useInstanceId( UnitControl );
const inputId = `block-columns-grid-gap-input-${ instanceId }`;

const units = useCustomUnits( {
availableUnits: useSetting( 'spacing.units' ) || [
'px',
'em',
'rem',
'vw',
'vh',
],
defaultValues: { px: '40', em: '2', rem: '2', vw: '5', vh: '5' },
} );

const handleOnChange = ( unprocessedValue ) => {
const inputValue =
unprocessedValue !== ''
? parseInt( unprocessedValue, 10 )
: undefined;

if ( isNaN( inputValue ) && inputValue !== undefined ) {
setTemporaryInput( unprocessedValue );
return;
}
setTemporaryInput( null );
onChange( inputValue );
if ( inputValue === undefined ) {
onUnitChange();
}
};

const handleOnBlur = () => {
if ( temporaryInput !== null ) {
setTemporaryInput( null );
}
};

const inputValue = temporaryInput !== null ? temporaryInput : value;
const min = 0;

return (
<BaseControl label={ __( 'Gap' ) } id={ inputId }>
<UnitControl
id={ inputId }
isResetValueOnUnitChange
min={ min }
onBlur={ handleOnBlur }
onChange={ handleOnChange }
onUnitChange={ onUnitChange }
step="1"
style={ { maxWidth: 80 } }
unit={ unit }
units={ units }
value={ inputValue }
/>
</BaseControl>
);
}

function ColumnsEditContainer( {
attributes,
clientId,
setAttributes,
updateAlignment,
updateColumns,
clientId,
} ) {
const { verticalAlignment } = attributes;
const { gridGap, gridGapUnit, verticalAlignment } = attributes;

const [ gridTemplateColumns, setGridTemplateColumns ] = useState(
undefined
);

const { count } = useSelect(
const { count, innerBlocks } = useSelect(
( select ) => {
return {
count: select( blockEditorStore ).getBlockCount( clientId ),
innerBlocks: select( blockEditorStore ).getBlocks( clientId ),
};
},
[ clientId ]
);

useEffect( () => {
setGridTemplateColumns(
getColumnWidthsAsGridColumnsValues( innerBlocks )
);
}, [ count, innerBlocks ] );

const gridGapWithUnit = gridGapUnit
? `${ gridGap }${ gridGapUnit }`
: gridGap;

const classes = classnames( {
[ `are-vertically-aligned-${ verticalAlignment }` ]: verticalAlignment,
} );

const blockProps = useBlockProps( {
className: classes,
style: {
gap: gridGapWithUnit || undefined,
gridTemplateColumns,
counterReset: 'grid-gap-' + gridGapWithUnit || undefined, // This is a hack to enforce re-rendering in Safari when the gap value changes.
},
} );

const innerBlocksProps = useInnerBlocksProps( blockProps, {
allowedBlocks: ALLOWED_BLOCKS,
orientation: 'horizontal',
Expand Down Expand Up @@ -101,6 +195,18 @@ function ColumnsEditContainer( {
) }
</Notice>
) }
<GridGapInput
value={ gridGap }
unit={ gridGapUnit }
onChange={ ( newGridGap ) =>
setAttributes( { gridGap: newGridGap } )
}
onUnitChange={ ( nextUnit ) =>
setAttributes( {
gridGapUnit: nextUnit,
} )
}
/>
</PanelBody>
</InspectorControls>
<div { ...innerBlocksProps } />
Expand Down
27 changes: 26 additions & 1 deletion packages/block-library/src/columns/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ function ColumnsEditContainer( {
isSelected,
onDeleteBlock,
innerWidths,
setAttributes,
updateInnerColumnWidth,
editorSidebarOpened,
} ) {
Expand All @@ -103,7 +104,12 @@ function ColumnsEditContainer( {
const screenWidth = Math.floor( Dimensions.get( 'window' ).width );
const globalStyles = useContext( GlobalStylesContext );

const { verticalAlignment, align } = attributes;
const {
verticalAlignment,
align,
gridGap,
gridGapUnit = 'em',
} = attributes;
const { width } = sizes || {};

const units = useCustomUnits( {
Expand Down Expand Up @@ -189,6 +195,14 @@ function ColumnsEditContainer( {
onChangeWidth( nextWidth, valueUnit, columnId );
};

const onGridGapChange = ( value ) => {
setAttributes( { gridGap: value } );
};

const onGridGapUnitChange = ( value ) => {
setAttributes( { gridGapUnit: value } );
};

const getColumnsSliders = useMemo( () => {
if ( ! editorSidebarOpened || ! isSelected ) {
return null;
Expand Down Expand Up @@ -257,6 +271,17 @@ function ColumnsEditContainer( {
type="stepper"
/>
{ getColumnsSliders }
<UnitControl
label={ __( 'Gap' ) }
min={ 0 }
max={ 30 }
unit={ gridGapUnit }
value={ gridGap }
onChange={ onGridGapChange }
onUnitChange={ onGridGapUnitChange }
units={ units }
key={ gridGapUnit }
/>
</PanelBody>
<PanelBody>
<FooterMessageControl
Expand Down
15 changes: 0 additions & 15 deletions packages/block-library/src/columns/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,6 @@
margin-right: 0;
}

// To do: remove horizontal margin override by the editor.
@include break-small() {
.editor-styles-wrapper
.block-editor-block-list__block.wp-block-column:nth-child(even) {
margin-left: $grid-unit-20 * 2;
}
}

@include break-medium() {
.editor-styles-wrapper
.block-editor-block-list__block.wp-block-column:not(:first-child) {
margin-left: $grid-unit-20 * 2;
}
}

// Individual columns do not have top and bottom margins on the frontend.
// So we make the editor match that.
// Needs specificity.
Expand Down
Loading