Skip to content

Commit

Permalink
Update padding block support for configurable sides
Browse files Browse the repository at this point in the history
This includes the addition of spacing.js which is a slight refactor so the padding support is no longer an ad-hoc addition within style.js and matches the approach with colors, typography, borders etc.
  • Loading branch information
aaronrobertshaw committed Apr 8, 2021
1 parent 8921929 commit 2fb3a26
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 39 deletions.
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
85 changes: 85 additions & 0 deletions packages/block-editor/src/hooks/spacing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* WordPress dependencies
*/
import { getBlockSupport } from '@wordpress/blocks';
import { Platform } from '@wordpress/element';

/**
* Internal dependencies
*/
import { PaddingEdit, useIsPaddingDisabled } from './padding';
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 } />
</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 );

return paddingDisabled;
};

/**
* 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 @@ -20,8 +20,7 @@ import { createHigherOrderComponent } from '@wordpress/compose';
import { BORDER_SUPPORT_KEY, BorderPanel } from './border';
import { COLOR_SUPPORT_KEY, ColorEdit } from './color';
import { TypographyPanel, TYPOGRAPHY_SUPPORT_KEYS } from './typography';
import { SPACING_SUPPORT_KEY, PaddingEdit } from './padding';
import SpacingPanelControl from '../components/spacing-panel-control';
import { SPACING_SUPPORT_KEY, SpacingPanel } from './spacing';

const styleSupportKeys = [
...TYPOGRAPHY_SUPPORT_KEYS,
Expand Down Expand Up @@ -140,7 +139,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 @@ -173,23 +172,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
4 changes: 4 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,17 @@ describe( 'getInlineStyles', () => {
color: { text: 'red', background: 'black' },
typography: { lineHeight: 1.5, fontSize: 10 },
border: { radius: 10 },
spacing: {
padding: { top: '10px' },
},
} )
).toEqual( {
backgroundColor: 'black',
borderRadius: 10,
color: 'red',
lineHeight: 1.5,
fontSize: 10,
paddingTop: '10px',
} );
} );
} );
Expand Down
74 changes: 55 additions & 19 deletions packages/edit-site/src/components/sidebar/spacing-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,20 @@ import {
__experimentalBoxControl as BoxControl,
PanelBody,
} from '@wordpress/components';
import { getBlockSupport } from '@wordpress/blocks';

/**
* Internal dependencies
*/
import { useEditorFeature } from '../editor/utils';

export function useHasSpacingPanel( { supports, name } ) {
export function useHasSpacingPanel( context ) {
const hasPadding = useHasPadding( context );

return hasPadding;
}

export function useHasPadding( { name, supports } ) {
return (
useEditorFeature( 'spacing.customPadding', name ) &&
supports.includes( 'padding' )
Expand All @@ -35,29 +42,58 @@ function useCustomUnits( { units, contextName } ) {
return usedUnits.length === 0 ? false : usedUnits;
}

export default function SpacingPanel( {
context: { name },
getStyle,
setStyle,
} ) {
function useCustomSides( blockName, feature ) {
const support = getBlockSupport( blockName, 'spacing' );

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

return support[ feature ];
}

function filterValuesBySides( values, sides ) {
if ( Object.entries( sides ).length === 0 ) {
// If no custom side configuration all sides are opted into by default.
return values;
}

// Only include sides opted into within filtered values.
return Object.keys( sides )
.filter( ( side ) => sides[ side ] )
.reduce(
( filtered, side ) => ( { ...filtered, [ side ]: values[ side ] } ),
{}
);
}

export default function SpacingPanel( { context, getStyle, setStyle } ) {
const { name } = context;
const showPaddingControl = useHasPadding( context );
const units = useCustomUnits( { contextName: name } );

const paddingValues = getStyle( name, 'padding' );
const setPaddingValues = ( { top, right, bottom, left } ) => {
setStyle( name, 'padding', {
top: top || paddingValues?.top,
right: right || paddingValues?.right,
bottom: bottom || paddingValues?.bottom,
left: left || paddingValues?.left,
} );
const paddingSides = useCustomSides( name, 'padding' );

const setPaddingValues = ( newPaddingValues ) => {
const padding = filterValuesBySides( newPaddingValues, paddingSides );
setStyle( name, 'padding', padding );
};

return (
<PanelBody title={ __( 'Spacing' ) }>
<BoxControl
values={ paddingValues }
onChange={ setPaddingValues }
label={ __( 'Padding' ) }
units={ units }
/>
{ showPaddingControl && (
<BoxControl
values={ paddingValues }
onChange={ setPaddingValues }
label={ __( 'Padding' ) }
sides={ paddingSides }
units={ units }
resetToInitialValues
/>
) }
</PanelBody>
);
}

0 comments on commit 2fb3a26

Please sign in to comment.