Skip to content

Commit

Permalink
Spacing Support: Add margin block support with configurable sides (#3…
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw authored May 11, 2021
1 parent e6129cf commit c1134bb
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 15 deletions.
7 changes: 7 additions & 0 deletions docs/how-to-guides/themes/theme-json.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ The settings section has the following structure and default values:
"wideSize": "1000px",
},
"spacing": {
"customMargin": false,
"customPadding": false, /* Supersedes add_theme_support('custom-spacing') */
"units": [ "px", "em", "rem", "vh", "vw" ], /* filter values, as in add_theme_support('custom-units', ... ) */
},
Expand Down Expand Up @@ -464,6 +465,12 @@ Each block declares which style properties it exposes via the [block supports me
"text": "value"
},
"spacing": {
"margin": {
"top": "value",
"right": "value",
"bottom": "value",
"left": "value"
},
"padding": {
"top": "value",
"right": "value",
Expand Down
7 changes: 5 additions & 2 deletions docs/reference-guides/block-api/block-supports.md
Original file line number Diff line number Diff line change
Expand Up @@ -497,26 +497,29 @@ supports: {
- Type: `Object`
- Default value: null
- Subproperties:
- `margin`: type `boolean` or `array`, default value `false`
- `padding`: type `boolean` or `array`, default value `false`
This value signals that a block supports some of the CSS style properties related to spacing. When it does, the block editor will show UI controls for the user to set their values, if [the theme declares support](/docs/how-to-guides/themes/theme-support.md#cover-block-padding).
```js
supports: {
spacing: {
margin: true, // Enable margin UI control.
padding: true, // Enable padding UI control.
}
}
```
When the block declares support for a specific spacing property, the attributes definition is extended to include the `style` attribute.
- `style`: attribute of `object` type with no default assigned. This is added when `padding` support is declared. It stores the custom values set by the user.
- `style`: attribute of `object` type with no default assigned. This is added when `margin` or `padding` support is declared. It stores the custom values set by the user.
```js
supports: {
spacing: {
padding: [ 'top', 'bottom' ], // Enable padding for arbitrary sides.
margin: [ 'top', 'bottom' ], // Enable margin for arbitrary sides.
padding: true, // Enable padding for all sides.
}
}
```
Expand Down
4 changes: 2 additions & 2 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
?>
<?php echo '.wp-container-' . $id; ?> > * {
<?php echo esc_html( safecss_filter_attr( $all_max_width_declaration ) ); ?>;
margin-left: auto;
margin-right: auto;
margin-left: auto !important;
margin-right: auto !important;
}

<?php echo '.wp-container-' . $id; ?> > .alignwide {
Expand Down
11 changes: 11 additions & 0 deletions lib/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ class WP_Theme_JSON {
'text' => null,
),
'spacing' => array(
'margin' => array(
'top' => null,
'right' => null,
'bottom' => null,
'left' => null,
),
'padding' => array(
'bottom' => null,
'left' => null,
Expand Down Expand Up @@ -91,6 +97,7 @@ class WP_Theme_JSON {
'custom' => null,
'layout' => null,
'spacing' => array(
'customMargin' => null,
'customPadding' => null,
'units' => null,
),
Expand Down Expand Up @@ -237,6 +244,10 @@ class WP_Theme_JSON {
'line-height' => array(
'value' => array( 'typography', 'lineHeight' ),
),
'margin' => array(
'value' => array( 'spacing', 'margin' ),
'properties' => array( 'top', 'right', 'bottom', 'left' ),
),
'padding' => array(
'value' => array( 'spacing', 'padding' ),
'properties' => array( 'top', 'right', 'bottom', 'left' ),
Expand Down
1 change: 1 addition & 0 deletions lib/experimental-default-theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
]
},
"spacing": {
"customMargin": false,
"customPadding": false,
"units": [ "px", "em", "rem", "vh", "vw" ]
},
Expand Down
4 changes: 2 additions & 2 deletions packages/block-editor/src/components/block-list/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export function LayoutStyle( { selector, layout = {} } ) {
? `
${ appendSelectors( selector, '> *' ) } {
max-width: ${ contentSize ?? wideSize };
margin-left: auto;
margin-right: auto;
margin-left: auto !important;
margin-right: auto !important;
}
${ appendSelectors( selector, '> [data-align="wide"]' ) } {
Expand Down
101 changes: 101 additions & 0 deletions packages/block-editor/src/hooks/margin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { Platform } from '@wordpress/element';
import { getBlockSupport } from '@wordpress/blocks';
import { __experimentalBoxControl as BoxControl } from '@wordpress/components';

/**
* Internal dependencies
*/
import useEditorFeature from '../components/use-editor-feature';
import { SPACING_SUPPORT_KEY, useCustomSides } from './spacing';
import { cleanEmptyObject } from './utils';
import { useCustomUnits } from '../components/unit-control';

/**
* Determines if there is margin support.
*
* @param {string|Object} blockType Block name or Block Type object.
* @return {boolean} Whether there is support.
*/
export function hasMarginSupport( blockType ) {
const support = getBlockSupport( blockType, SPACING_SUPPORT_KEY );
return !! ( true === support || support?.margin );
}

/**
* Custom hook that checks if margin settings have been disabled.
*
* @param {string} name The name of the block.
* @return {boolean} Whether margin setting is disabled.
*/
export function useIsMarginDisabled( { name: blockName } = {} ) {
const isDisabled = ! useEditorFeature( 'spacing.customMargin' );
return ! hasMarginSupport( blockName ) || isDisabled;
}

/**
* Inspector control panel containing the margin related configuration
*
* @param {Object} props Block props.
* @return {WPElement} Margin edit element.
*/
export function MarginEdit( props ) {
const {
name: blockName,
attributes: { style },
setAttributes,
} = props;

const units = useCustomUnits();
const sides = useCustomSides( blockName, 'margin' );

if ( ! hasMarginSupport( blockName ) ) {
return null;
}

const onChange = ( next ) => {
const newStyle = {
...style,
spacing: {
...style?.spacing,
margin: next,
},
};

setAttributes( {
style: cleanEmptyObject( newStyle ),
} );
};

const onChangeShowVisualizer = ( next ) => {
const newStyle = {
...style,
visualizers: {
margin: next,
},
};

setAttributes( {
style: cleanEmptyObject( newStyle ),
} );
};

return Platform.select( {
web: (
<>
<BoxControl
values={ style?.spacing?.margin }
onChange={ onChange }
onChangeShowVisualizer={ onChangeShowVisualizer }
label={ __( 'Margin' ) }
sides={ sides }
units={ units }
/>
</>
),
native: null,
} );
}
9 changes: 6 additions & 3 deletions packages/block-editor/src/hooks/spacing.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getBlockSupport } from '@wordpress/blocks';
* Internal dependencies
*/
import InspectorControls from '../components/inspector-controls';
import { MarginEdit, hasMarginSupport, useIsMarginDisabled } from './margin';
import {
PaddingEdit,
hasPaddingSupport,
Expand All @@ -36,13 +37,14 @@ export function SpacingPanel( props ) {
<InspectorControls key="spacing">
<PanelBody title={ __( 'Spacing' ) }>
<PaddingEdit { ...props } />
<MarginEdit { ...props } />
</PanelBody>
</InspectorControls>
);
}

/**
* Determine whether there is block support for padding.
* Determine whether there is block support for padding or margins.
*
* @param {string} blockName Block name.
* @return {boolean} Whether there is support.
Expand All @@ -52,7 +54,7 @@ export function hasSpacingSupport( blockName ) {
return false;
}

return hasPaddingSupport( blockName );
return hasPaddingSupport( blockName ) || hasMarginSupport( blockName );
}

/**
Expand All @@ -63,8 +65,9 @@ export function hasSpacingSupport( blockName ) {
*/
const useIsSpacingDisabled = ( props = {} ) => {
const paddingDisabled = useIsPaddingDisabled( props );
const marginDisabled = useIsMarginDisabled( props );

return paddingDisabled;
return paddingDisabled && marginDisabled;
};

/**
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/hooks/test/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe( 'getInlineStyles', () => {
},
spacing: {
padding: { top: '10px' },
margin: { bottom: '15px' },
},
} )
).toEqual( {
Expand All @@ -36,6 +37,7 @@ describe( 'getInlineStyles', () => {
color: 'red',
lineHeight: 1.5,
fontSize: 10,
marginBottom: '15px',
paddingTop: '10px',
} );
} );
Expand Down
5 changes: 5 additions & 0 deletions packages/blocks/src/api/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = {
value: [ 'typography', 'lineHeight' ],
support: [ 'lineHeight' ],
},
margin: {
value: [ 'spacing', 'margin' ],
support: [ 'spacing', 'margin' ],
properties: [ 'top', 'right', 'bottom', 'left' ],
},
padding: {
value: [ 'spacing', 'padding' ],
support: [ 'spacing', 'padding' ],
Expand Down
36 changes: 30 additions & 6 deletions packages/edit-site/src/components/sidebar/spacing-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,21 @@ const CSS_UNITS = [

export function useHasSpacingPanel( context ) {
const hasPadding = useHasPadding( context );
const hasMargin = useHasMargin( context );

return hasPadding;
return hasPadding || hasMargin;
}

export function useHasPadding( { name, supports } ) {
return (
useEditorFeature( 'spacing.customPadding', name ) &&
supports.includes( 'padding' )
);
function useHasPadding( { name, supports } ) {
const settings = useEditorFeature( 'spacing.customPadding', name );

return settings && supports.includes( 'padding' );
}

function useHasMargin( { name, supports } ) {
const settings = useEditorFeature( 'spacing.customMargin', name );

return settings && supports.includes( 'margin' );
}

function filterUnitsWithSettings( settings = [], units = [] ) {
Expand Down Expand Up @@ -88,6 +94,7 @@ function filterValuesBySides( values, sides ) {
export default function SpacingPanel( { context, getStyle, setStyle } ) {
const { name } = context;
const showPaddingControl = useHasPadding( context );
const showMarginControl = useHasMargin( context );
const units = useCustomUnits( { contextName: name, units: CSS_UNITS } );

const paddingValues = getStyle( name, 'padding' );
Expand All @@ -98,6 +105,14 @@ export default function SpacingPanel( { context, getStyle, setStyle } ) {
setStyle( name, 'padding', padding );
};

const marginValues = getStyle( name, 'margin' );
const marginSides = useCustomSides( name, 'margin' );

const setMarginValues = ( newMarginValues ) => {
const margin = filterValuesBySides( newMarginValues, marginSides );
setStyle( name, 'margin', margin );
};

return (
<PanelBody title={ __( 'Spacing' ) }>
{ showPaddingControl && (
Expand All @@ -109,6 +124,15 @@ export default function SpacingPanel( { context, getStyle, setStyle } ) {
units={ units }
/>
) }
{ showMarginControl && (
<BoxControl
values={ marginValues }
onChange={ setMarginValues }
label={ __( 'Margin' ) }
sides={ marginSides }
units={ units }
/>
) }
</PanelBody>
);
}

0 comments on commit c1134bb

Please sign in to comment.