Skip to content

Commit

Permalink
Add margin block support with configurable sides
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed Apr 30, 2021
1 parent 3b815c4 commit c5bd1a3
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 9 deletions.
11 changes: 11 additions & 0 deletions lib/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ class WP_Theme_JSON {
'text' => null,
),
'spacing' => array(
'margin' => array(
'top' => null,
'right' => null,
'bottom' => null,
'left' => null,
),
'padding' => array(
'top' => null,
'right' => null,
Expand Down Expand Up @@ -111,6 +117,7 @@ class WP_Theme_JSON {
'duotone' => null,
),
'spacing' => array(
'customMargin' => null,
'customPadding' => null,
'units' => null,
),
Expand Down Expand Up @@ -259,6 +266,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
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 @@ -65,6 +65,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 c5bd1a3

Please sign in to comment.