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

Block spacing: add axial gap block support #35454

Closed
wants to merge 9 commits into from
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
$style .= "$selector .alignright { float: right; margin-left: 2em; }";
if ( $has_block_gap_support ) {
$style .= "$selector > * { margin-top: 0; margin-bottom: 0; }";
$style .= "$selector > * + * { margin-top: var( --wp--style--block-gap ); margin-bottom: 0; }";
$style .= "$selector > * + * { margin-top: var( --wp--style--block-row-gap ); margin-bottom: 0; }";
}
} elseif ( 'flex' === $layout_type ) {
$layout_orientation = isset( $layout['orientation'] ) ? $layout['orientation'] : 'horizontal';
Expand All @@ -89,9 +89,9 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
$style = "$selector {";
$style .= 'display: flex;';
if ( $has_block_gap_support ) {
$style .= 'gap: var( --wp--style--block-gap, 0.5em );';
$style .= 'gap: var( --wp--style--block-row-gap, 0.5em ) var( --wp--style--block-column-gap, 0.5em );';
} else {
$style .= 'gap: 0.5em;';
$style .= 'gap: 0.5em 0.5em;';
}
$style .= "flex-wrap: $flex_wrap;";
if ( 'horizontal' === $layout_orientation ) {
Expand Down
40 changes: 31 additions & 9 deletions lib/block-supports/spacing.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,22 +108,44 @@ function gutenberg_render_spacing_gap_support( $block_content, $block ) {

$gap_value = $block['attrs']['style']['spacing']['blockGap'];

// Skip if gap value contains unsupported characters.
// Regex for CSS value borrowed from `safecss_filter_attr`, and used here
// Regex to test CSS gap value for unsupported characters.
// Borrowed from `safecss_filter_attr`, and used here
// because we only want to match against the value, not the CSS attribute.
if ( preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ) {
return $block_content;
$regex_pattern = '%[\\\(&=}]|/\*%';
$styles = array();

if ( is_array( $gap_value ) ) {
$gap_row_value_is_valid = isset( $gap_value['row'] ) && ! preg_match( $regex_pattern, $gap_value['row'] );
$gap_column_value_is_valid = isset( $gap_value['column'] ) && ! preg_match( $regex_pattern, $gap_value['column'] );

if ( $gap_row_value_is_valid && $gap_column_value_is_valid ) {
$gap_shorthand_value = $gap_value['row'] === $gap_value['column'] ? esc_attr( $gap_value['row'] ) : esc_attr( $gap_value['row'] ) . ' ' . esc_attr( $gap_value['column'] );
$styles[] = sprintf( '--wp--style--block-gap: %s;', $gap_shorthand_value );
}

if ( $gap_row_value_is_valid ) {
$styles[] = sprintf( '--wp--style--block-row-gap: %s;', esc_attr( $gap_value['row'] ) );
}

if ( $gap_column_value_is_valid ) {
$styles[] = sprintf( '--wp--style--block-column-gap: %s;', esc_attr( $gap_value['column'] ) );
}
} else {
if ( preg_match( $regex_pattern, $gap_value ) ) {
return $block_content;
}

$styles[] = sprintf( '--wp--style--block-gap: %s;', esc_attr( $gap_value ) );
$styles[] = sprintf( '--wp--style--block-row-gap: %s;', esc_attr( $gap_value ) );
$styles[] = sprintf( '--wp--style--block-column-gap: %s;', esc_attr( $gap_value ) );
}

$style = sprintf(
'--wp--style--block-gap: %s',
esc_attr( $gap_value )
);
$style = implode( ' ', $styles );

// Attempt to update an existing style attribute on the wrapper element.
$injected_style = preg_replace(
'/^([^>.]+?)(' . preg_quote( 'style="', '/' ) . ')(?=.+?>)/',
'$1$2' . $style . '; ',
'$1$2' . $style . ' ',
$block_content,
1
);
Expand Down
66 changes: 34 additions & 32 deletions lib/compat/wordpress-5.9/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,37 +147,39 @@ class WP_Theme_JSON_Gutenberg {
* path to the value in theme.json & block attributes.
*/
const PROPERTIES_METADATA = array(
'background' => array( 'color', 'gradient' ),
'background-color' => array( 'color', 'background' ),
'border-radius' => array( 'border', 'radius' ),
'border-top-left-radius' => array( 'border', 'radius', 'topLeft' ),
'border-top-right-radius' => array( 'border', 'radius', 'topRight' ),
'border-bottom-left-radius' => array( 'border', 'radius', 'bottomLeft' ),
'border-bottom-right-radius' => array( 'border', 'radius', 'bottomRight' ),
'border-color' => array( 'border', 'color' ),
'border-width' => array( 'border', 'width' ),
'border-style' => array( 'border', 'style' ),
'color' => array( 'color', 'text' ),
'font-family' => array( 'typography', 'fontFamily' ),
'font-size' => array( 'typography', 'fontSize' ),
'font-style' => array( 'typography', 'fontStyle' ),
'font-weight' => array( 'typography', 'fontWeight' ),
'letter-spacing' => array( 'typography', 'letterSpacing' ),
'line-height' => array( 'typography', 'lineHeight' ),
'margin' => array( 'spacing', 'margin' ),
'margin-top' => array( 'spacing', 'margin', 'top' ),
'margin-right' => array( 'spacing', 'margin', 'right' ),
'margin-bottom' => array( 'spacing', 'margin', 'bottom' ),
'margin-left' => array( 'spacing', 'margin', 'left' ),
'padding' => array( 'spacing', 'padding' ),
'padding-top' => array( 'spacing', 'padding', 'top' ),
'padding-right' => array( 'spacing', 'padding', 'right' ),
'padding-bottom' => array( 'spacing', 'padding', 'bottom' ),
'padding-left' => array( 'spacing', 'padding', 'left' ),
'--wp--style--block-gap' => array( 'spacing', 'blockGap' ),
'text-decoration' => array( 'typography', 'textDecoration' ),
'text-transform' => array( 'typography', 'textTransform' ),
'filter' => array( 'filter', 'duotone' ),
'background' => array( 'color', 'gradient' ),
'background-color' => array( 'color', 'background' ),
'border-radius' => array( 'border', 'radius' ),
'border-top-left-radius' => array( 'border', 'radius', 'topLeft' ),
'border-top-right-radius' => array( 'border', 'radius', 'topRight' ),
'border-bottom-left-radius' => array( 'border', 'radius', 'bottomLeft' ),
'border-bottom-right-radius' => array( 'border', 'radius', 'bottomRight' ),
'border-color' => array( 'border', 'color' ),
'border-width' => array( 'border', 'width' ),
'border-style' => array( 'border', 'style' ),
'color' => array( 'color', 'text' ),
'font-family' => array( 'typography', 'fontFamily' ),
'font-size' => array( 'typography', 'fontSize' ),
'font-style' => array( 'typography', 'fontStyle' ),
'font-weight' => array( 'typography', 'fontWeight' ),
'letter-spacing' => array( 'typography', 'letterSpacing' ),
'line-height' => array( 'typography', 'lineHeight' ),
'margin' => array( 'spacing', 'margin' ),
'margin-top' => array( 'spacing', 'margin', 'top' ),
'margin-right' => array( 'spacing', 'margin', 'right' ),
'margin-bottom' => array( 'spacing', 'margin', 'bottom' ),
'margin-left' => array( 'spacing', 'margin', 'left' ),
'padding' => array( 'spacing', 'padding' ),
'padding-top' => array( 'spacing', 'padding', 'top' ),
'padding-right' => array( 'spacing', 'padding', 'right' ),
'padding-bottom' => array( 'spacing', 'padding', 'bottom' ),
'padding-left' => array( 'spacing', 'padding', 'left' ),
'--wp--style--block-gap' => array( 'spacing', 'blockGap' ),
'--wp--style--block-row-gap' => array( 'spacing', 'blockGap', 'row' ),
'--wp--style--block-column-gap' => array( 'spacing', 'blockGap', 'column' ),
'text-decoration' => array( 'typography', 'textDecoration' ),
'text-transform' => array( 'typography', 'textTransform' ),
'filter' => array( 'filter', 'duotone' ),
);

/**
Expand Down Expand Up @@ -743,7 +745,7 @@ private function get_block_classes( $style_nodes ) {
$has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null;
if ( $has_block_gap_support ) {
$block_rules .= '.wp-site-blocks > * { margin-top: 0; margin-bottom: 0; }';
$block_rules .= '.wp-site-blocks > * + * { margin-top: var( --wp--style--block-gap ); }';
$block_rules .= '.wp-site-blocks > * + * { margin-top: var( --wp--style--block-column-gap ); }';
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/default-editor-styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ body {
font-size: 18px;
line-height: 1.5;
--wp--style--block-gap: 2em;
--wp--style--block-row-gap: 2em;
--wp--style--block-column-gap: 2em;
}

p {
Expand Down
61 changes: 51 additions & 10 deletions packages/block-editor/src/hooks/gap.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Platform } from '@wordpress/element';
import { getBlockSupport } from '@wordpress/blocks';
import {
__experimentalUseCustomUnits as useCustomUnits,
__experimentalBoxControl as BoxControl,
__experimentalUnitControl as UnitControl,
} from '@wordpress/components';

Expand All @@ -14,7 +15,7 @@ import {
*/
import { __unstableUseBlockRef as useBlockRef } from '../components/block-list/use-block-props/use-block-refs';
import useSetting from '../components/use-setting';
import { SPACING_SUPPORT_KEY } from './dimensions';
import { AXIAL_SIDES, SPACING_SUPPORT_KEY, useCustomSides } from './dimensions';
import { cleanEmptyObject } from './utils';

/**
Expand Down Expand Up @@ -82,6 +83,7 @@ export function GapEdit( props ) {
const {
clientId,
attributes: { style },
name: blockName,
setAttributes,
} = props;

Expand All @@ -95,18 +97,27 @@ export function GapEdit( props ) {
],
} );

const sides = useCustomSides( blockName, 'blockGap' );
const splitOnAxis =
sides && sides.some( ( side ) => AXIAL_SIDES.includes( side ) );
const ref = useBlockRef( clientId );

if ( useIsGapDisabled( props ) ) {
return null;
}

const onChange = ( next ) => {
const row = next?.top ?? next;
const column = next?.left ?? next;

const newStyle = {
...style,
spacing: {
...style?.spacing,
blockGap: next,
blockGap: {
row,
column,
},
},
};

Expand All @@ -128,17 +139,47 @@ export function GapEdit( props ) {
}
};

const blockGapValue = style?.spacing?.blockGap;
const rowValue = blockGapValue?.row;
const columnValue = blockGapValue?.column;
// Check for blockGap string values, e.g., "blockGap":"169px", on pre-axial blocks.
const isStringValue = typeof blockGapValue === 'string';

const boxValues = {
top: isStringValue ? blockGapValue : rowValue,
right: isStringValue ? blockGapValue : columnValue,
bottom: isStringValue ? blockGapValue : rowValue,
left: isStringValue ? blockGapValue : columnValue,
};

// The default combined value we'll take from row.
const defaultValue = boxValues.top;

return Platform.select( {
web: (
<>
<UnitControl
label={ __( 'Block spacing' ) }
__unstableInputWidth="80px"
min={ 0 }
onChange={ onChange }
units={ units }
value={ style?.spacing?.blockGap }
/>
{ splitOnAxis ? (
<BoxControl
label={ __( 'Block spacing' ) }
min={ 0 }
onChange={ onChange }
units={ units }
sides={ sides }
values={ boxValues }
allowReset={ false }
splitOnAxis={ splitOnAxis }
/>
) : (
<UnitControl
label={ __( 'Block spacing' ) }
__unstableInputWidth="80px"
min={ 0 }
onChange={ onChange }
units={ units }
// Default to `row` for combined values.
value={ defaultValue }
/>
) }
</>
),
native: null,
Expand Down
4 changes: 2 additions & 2 deletions packages/block-editor/src/layouts/flex.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ export default {
display: flex;
gap: ${
hasBlockGapStylesSupport
? 'var( --wp--style--block-gap, 0.5em )'
: '0.5em'
? 'var( --wp--style--block-row-gap, 0.5em ) var( --wp--style--block-column-gap, 0.5em )'
: '0.5em 0.5em'
};
flex-wrap: ${ flexWrap };
${ orientation === 'horizontal' ? rowOrientation : columnOrientation }
Expand Down
2 changes: 1 addition & 1 deletion packages/block-editor/src/layouts/flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export default {
margin-bottom: 0;
}
${ appendSelectors( selector, '> * + *' ) } {
margin-top: var( --wp--style--block-gap );
margin-top: var( --wp--style--block-column-gap );
}
`;
}
Expand Down
6 changes: 3 additions & 3 deletions packages/block-library/src/button/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ $blocks-block__margin: 0.5em;
}

&.wp-block-button__width-25 {
width: calc(25% - (var(--wp--style--block-gap, #{$blocks-block__margin}) * 0.75));
width: calc(25% - (var(--wp--style--block-column-gap, #{$blocks-block__margin}) * 0.75));
}

&.wp-block-button__width-50 {
width: calc(50% - (var(--wp--style--block-gap, #{$blocks-block__margin}) * 0.5));
width: calc(50% - (var(--wp--style--block-column-gap, #{$blocks-block__margin}) * 0.5));
}

&.wp-block-button__width-75 {
width: calc(75% - (var(--wp--style--block-gap, #{$blocks-block__margin}) * 0.25));
width: calc(75% - (var(--wp--style--block-column-gap, #{$blocks-block__margin}) * 0.25));
}

&.wp-block-button__width-100 {
Expand Down
4 changes: 2 additions & 2 deletions packages/block-library/src/columns/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
@include break-small() {
.editor-styles-wrapper
.block-editor-block-list__block.wp-block-column:nth-child(even) {
margin-left: var(--wp--style--block-gap, 2em);
margin-left: var(--wp--style--block-column-gap, 2em);
}
}

@include break-medium() {
.editor-styles-wrapper
.block-editor-block-list__block.wp-block-column:not(:first-child) {
margin-left: var(--wp--style--block-gap, 2em);
margin-left: var(--wp--style--block-column-gap, 2em);
}
}

Expand Down
8 changes: 4 additions & 4 deletions packages/block-library/src/columns/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@
// As with mobile styles, this must be important since the Column
// assigns its own width as an inline style, which should take effect
// starting at `break-medium`.
flex-basis: calc(50% - calc(var(--wp--style--block-gap, 2em) / 2)) !important;
flex-basis: calc(50% - calc(var(--wp--style--block-column-gap, 2em) / 2)) !important;
flex-grow: 0;
}

// Add space between the multiple columns. Themes can customize this if they wish to work differently.
// Only apply this beyond the mobile breakpoint, as there's only a single column on mobile.
&:nth-child(even) {
margin-left: var(--wp--style--block-gap, 2em);
margin-left: var(--wp--style--block-column-gap, 2em);
}
}

Expand All @@ -74,7 +74,7 @@

// When columns are in a single row, add space before all except the first.
&:not(:first-child) {
margin-left: var(--wp--style--block-gap, 2em);
margin-left: var(--wp--style--block-column-gap, 2em);
}
}
}
Expand All @@ -95,7 +95,7 @@

// When columns are in a single row, add space before all except the first.
&:not(:first-child) {
margin-left: var(--wp--style--block-gap, 2em);
margin-left: var(--wp--style--block-column-gap, 2em);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/block-library/src/navigation/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ button.wp-block-navigation-item__content {
// Apply top padding to nested submenus.
.wp-block-navigation__submenu-container,
.wp-block-navigation__container {
padding-top: var(--wp--style--block-gap, 2em);
padding-top: var(--wp--style--block-row-gap, 2em);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/block-library/src/social-links/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
}
},
"spacing": {
"blockGap": true,
"blockGap": [ "horizontal", "vertical" ],
"margin": [ "top", "bottom" ],
"units": [ "px", "em", "rem", "vh", "vw" ],
"__experimentalDefaultControls": {
Expand Down
4 changes: 4 additions & 0 deletions packages/blocks/src/api/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = {
'--wp--style--block-gap': {
value: [ 'spacing', 'blockGap' ],
support: [ 'spacing', 'blockGap' ],
properties: {
'--wp--style--block-column-gap': 'column',
'--wp--style--block-row-gap': 'row',
},
},
};

Expand Down