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 Support: Add configurable sides and margins to spacing support #30333

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
12 changes: 12 additions & 0 deletions lib/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,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 @@ -152,6 +158,7 @@ class WP_Theme_JSON {
),
'spacing' => array(
'customPadding' => null,
'customMargin' => null,
'units' => null,
),
'typography' => array(
Expand Down Expand Up @@ -309,6 +316,11 @@ class WP_Theme_JSON {
'value' => array( 'typography', 'lineHeight' ),
'support' => array( 'lineHeight' ),
),
'margin' => array(
'value' => array( 'spacing', 'margin' ),
'support' => array( 'spacing', 'margin' ),
'properties' => array( 'top', 'right', 'bottom', 'left' ),
),
'padding' => array(
'value' => array( 'spacing', 'padding' ),
'support' => array( 'spacing', 'padding' ),
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,
} );
}
30 changes: 25 additions & 5 deletions packages/block-editor/src/hooks/padding.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,33 @@ 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';

export const SPACING_SUPPORT_KEY = 'spacing';

const hasPaddingSupport = ( blockName ) => {
const spacingSupport = getBlockSupport( blockName, SPACING_SUPPORT_KEY );
return spacingSupport && spacingSupport.padding !== false;
/**
* Determines if there is padding support.
*
* @param {string|Object} blockType Block name or Block Type object.
* @return {boolean} Whether there is support.
*/
const hasPaddingSupport = ( blockType ) => {
const support = getBlockSupport( blockType, SPACING_SUPPORT_KEY );
return !! ( true === support || support?.padding );
};

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

/**
* Inspector control panel containing the padding related configuration
*
Expand All @@ -34,6 +51,7 @@ export function PaddingEdit( props ) {
} = props;

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

if ( ! hasPaddingSupport( blockName ) ) {
return null;
Expand All @@ -43,6 +61,7 @@ export function PaddingEdit( props ) {
const newStyle = {
...style,
spacing: {
...style?.spacing,
padding: next,
},
};
Expand Down Expand Up @@ -73,6 +92,7 @@ export function PaddingEdit( props ) {
onChange={ onChange }
onChangeShowVisualizer={ onChangeShowVisualizer }
label={ __( 'Padding' ) }
sides={ sides }
units={ units }
/>
</>
Expand Down
88 changes: 88 additions & 0 deletions packages/block-editor/src/hooks/spacing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* WordPress dependencies
*/
import { getBlockSupport } from '@wordpress/blocks';
import { Platform } from '@wordpress/element';

/**
* Internal dependencies
*/
import { PaddingEdit, useIsPaddingDisabled } from './padding';
import { MarginEdit, useIsMarginDisabled } from './margin';
import SpacingPanelControl from '../components/spacing-panel-control';

export const SPACING_SUPPORT_KEY = 'spacing';

/**
* Inspector controls for spacing support.
*
* @param {Object} props Block props.
* @return {WPElement} Inspector controls for spacing support features.
*/
export function SpacingPanel( props ) {
const isDisabled = useIsSpacingDisabled( props );
const isSupported = hasSpacingSupport( props.name );

if ( isDisabled || ! isSupported ) {
return null;
}

return (
<SpacingPanelControl key="spacing">
<PaddingEdit { ...props } />
<MarginEdit { ...props } />
</SpacingPanelControl>
);
}

/**
* Determine whether there is block support for padding or margins.
*
* @param {string} blockName Block name.
* @return {boolean} Whether there is support.
*/
export function hasSpacingSupport( blockName ) {
if ( Platform.OS !== 'web' ) {
return false;
}

const support = getBlockSupport( blockName, SPACING_SUPPORT_KEY );

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

/**
* Determines whether spacing support has been disabled.
*
* @param {Object} props Block properties.
* @return {boolean} If spacing support is completely disabled.
*/
const useIsSpacingDisabled = ( props = {} ) => {
const paddingDisabled = useIsPaddingDisabled( props );
const marginDisabled = useIsMarginDisabled( props );

return paddingDisabled && marginDisabled;
};

/**
* Custom hook to retrieve which padding/margin is supported
* e.g. top, right, bottom or left.
*
* Sides are opted into by default. It is only if a specific side is set to
* false that it is omitted.
*
* @param {string} blockName Block name.
* @param {string} feature The feature custom sides relate to e.g. padding or margins.
* @return {Object} Sides supporting custom margin.
*/
export function useCustomSides( blockName, feature ) {
const support = getBlockSupport( blockName, SPACING_SUPPORT_KEY );

// Return empty config when setting is boolean as theme isn't setting
// arbitrary sides.
if ( typeof support[ feature ] === 'boolean' ) {
return {};
}

return support[ feature ];
}
18 changes: 3 additions & 15 deletions packages/block-editor/src/hooks/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ import { createHigherOrderComponent } from '@wordpress/compose';
*/
import { BORDER_SUPPORT_KEY, BorderPanel } from './border';
import { COLOR_SUPPORT_KEY, ColorEdit } from './color';
import { SPACING_SUPPORT_KEY, SpacingPanel } from './spacing';
import { TypographyPanel, TYPOGRAPHY_SUPPORT_KEYS } from './typography';
import { SPACING_SUPPORT_KEY, PaddingEdit } from './padding';
import SpacingPanelControl from '../components/spacing-panel-control';

const styleSupportKeys = [
...TYPOGRAPHY_SUPPORT_KEYS,
Expand Down Expand Up @@ -119,7 +118,7 @@ export function addSaveProps( props, blockType, attributes ) {
}

/**
* Filters registered block settings to extand the block edit wrapper
* Filters registered block settings to extend the block edit wrapper
* to apply the desired styles and classnames properly.
*
* @param {Object} settings Original block settings
Expand Down Expand Up @@ -152,23 +151,12 @@ export function addEditProps( settings ) {
*/
export const withBlockControls = createHigherOrderComponent(
( BlockEdit ) => ( props ) => {
const { name: blockName } = props;

const hasSpacingSupport = hasBlockSupport(
blockName,
SPACING_SUPPORT_KEY
);

return [
<TypographyPanel key="typography" { ...props } />,
<BorderPanel key="border" { ...props } />,
<ColorEdit key="colors" { ...props } />,
<BlockEdit key="edit" { ...props } />,
hasSpacingSupport && (
<SpacingPanelControl key="spacing">
<PaddingEdit { ...props } />
</SpacingPanelControl>
),
<SpacingPanel key="spacing" { ...props } />,
];
},
'withToolbarControls'
Expand Down
6 changes: 6 additions & 0 deletions packages/block-editor/src/hooks/test/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ describe( 'getInlineStyles', () => {
color: { text: 'red', background: 'black' },
typography: { lineHeight: 1.5, fontSize: 10 },
border: { radius: 10 },
spacing: {
padding: { top: '10px' },
margin: { bottom: '15px' },
},
} )
).toEqual( {
backgroundColor: 'black',
borderRadius: 10,
color: 'red',
lineHeight: 1.5,
fontSize: 10,
marginBottom: '15px',
paddingTop: '10px',
} );
} );
} );
5 changes: 5 additions & 0 deletions packages/blocks/src/api/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,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
Loading