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 8, 2021
1 parent fac2ed0 commit 8ae61ea
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 5 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 @@ -100,6 +100,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 @@ -132,6 +138,7 @@ class WP_Theme_JSON {
'palette' => null,
),
'spacing' => array(
'customMargin' => null,
'customPadding' => null,
'units' => null,
),
Expand Down Expand Up @@ -277,6 +284,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
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import useEditorFeature from '../use-editor-feature';

export default function SpacingPanelControl( { children, ...props } ) {
const isSpacingEnabled = useEditorFeature( 'spacing.customPadding' );
const isMarginEnabled = useEditorFeature( 'spacing.customMargin' );

if ( ! isSpacingEnabled ) return null;
if ( ! isSpacingEnabled && ! isMarginEnabled ) {
return null;
}

return (
<InspectorControls { ...props }>
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.
*/
const 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 @@ -7,6 +7,7 @@ import { Platform } from '@wordpress/element';
/**
* Internal dependencies
*/
import { MarginEdit, useIsMarginDisabled } from './margin';
import { PaddingEdit, useIsPaddingDisabled } from './padding';
import SpacingPanelControl from '../components/spacing-panel-control';

Expand All @@ -29,12 +30,13 @@ export function SpacingPanel( props ) {
return (
<SpacingPanelControl key="spacing">
<PaddingEdit { ...props } />
<MarginEdit { ...props } />
</SpacingPanelControl>
);
}

/**
* 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 @@ -46,7 +48,7 @@ export function hasSpacingSupport( blockName ) {

const support = getBlockSupport( blockName, SPACING_SUPPORT_KEY );

return !! ( true === support || support?.padding );
return !! ( true === support || support?.padding || support?.margin );
}

/**
Expand All @@ -57,8 +59,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 @@ -20,6 +20,7 @@ describe( 'getInlineStyles', () => {
border: { radius: 10 },
spacing: {
padding: { top: '10px' },
margin: { bottom: '15px' },
},
} )
).toEqual( {
Expand All @@ -28,6 +29,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
28 changes: 27 additions & 1 deletion packages/edit-site/src/components/sidebar/spacing-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import { useEditorFeature } from '../editor/utils';

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

return hasPadding;
return hasPadding || hasMargin;
}

export function useHasPadding( { name, supports } ) {
Expand All @@ -26,6 +27,12 @@ export function useHasPadding( { name, supports } ) {
);
}

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

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

function filterUnitsWithSettings( settings = [], units = [] ) {
return units.filter( ( unit ) => {
return settings.includes( unit.value );
Expand Down Expand Up @@ -72,6 +79,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 } );

const paddingValues = getStyle( name, 'padding' );
Expand All @@ -82,6 +90,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 @@ -94,6 +110,16 @@ export default function SpacingPanel( { context, getStyle, setStyle } ) {
resetToInitialValues
/>
) }
{ showMarginControl && (
<BoxControl
values={ marginValues }
onChange={ setMarginValues }
label={ __( 'Margin' ) }
sides={ marginSides }
units={ units }
resetToInitialValues
/>
) }
</PanelBody>
);
}

0 comments on commit 8ae61ea

Please sign in to comment.