Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Update global styles spacing panel
- Fixes bug where BoxControl cannot be reset in Global Styles
- Updates the spacing panel to include margins and custom sides
  • Loading branch information
aaronrobertshaw committed Apr 7, 2021
commit 3730244dc0973200520a715312f16cf8ffd076a2
5 changes: 3 additions & 2 deletions lib/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class WP_Theme_JSON {
'text' => null,
),
'spacing' => array(
'margin' => array(
'margin' => array(
'top' => null,
'right' => null,
'bottom' => null,
Expand Down Expand Up @@ -158,6 +158,7 @@ class WP_Theme_JSON {
),
'spacing' => array(
'customPadding' => null,
'customMargin' => null,
'units' => null,
),
'typography' => array(
Expand Down Expand Up @@ -315,7 +316,7 @@ class WP_Theme_JSON {
'value' => array( 'typography', 'lineHeight' ),
'support' => array( 'lineHeight' ),
),
'margin' => array(
'margin' => array(
'value' => array( 'spacing', 'margin' ),
'support' => array( 'spacing', 'margin' ),
'properties' => array( 'top', 'right', 'bottom', 'left' ),
Expand Down
16 changes: 11 additions & 5 deletions packages/components/src/box-control/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { noop } from 'lodash';
* WordPress dependencies
*/
import { useInstanceId } from '@wordpress/compose';
import { useState } from '@wordpress/element';
import { useRef, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
Expand Down Expand Up @@ -52,13 +52,21 @@ export default function BoxControl( {
values: valuesProp,
units,
sides,
resetToInitialValues = false,
} ) {
const [ values, setValues ] = useControlledState( valuesProp, {
fallback: DEFAULT_VALUES,
} );
const inputValues = values || DEFAULT_VALUES;
const hasInitialValue = isValuesDefined( valuesProp );

// Determine which values the reset button should apply.
// Global styles generally prefer to reset to the initial value likely
// coming from a theme.
const resetValues = useRef(
resetToInitialValues && valuesProp ? valuesProp : DEFAULT_VALUES
);

const [ isDirty, setIsDirty ] = useState( hasInitialValue );
const [ isLinked, setIsLinked ] = useState(
! hasInitialValue || ! isValuesMixed( inputValues )
Expand Down Expand Up @@ -93,10 +101,8 @@ export default function BoxControl( {
};

const handleOnReset = () => {
const initialValues = DEFAULT_VALUES;

onChange( initialValues );
setValues( initialValues );
onChange( resetValues.current );
setValues( resetValues.current );
setIsDirty( false );
};

Expand Down
100 changes: 81 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,19 +6,33 @@ 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 );
const hasMargin = useHasMargin( context );

return hasPadding || hasMargin;
}

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

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 All @@ -35,29 +49,77 @@ 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 showMarginControl = useHasMargin( 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 );
};

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' ) }>
<BoxControl
values={ paddingValues }
onChange={ setPaddingValues }
label={ __( 'Padding' ) }
units={ units }
/>
{ showPaddingControl && (
<BoxControl
values={ paddingValues }
onChange={ setPaddingValues }
label={ __( 'Padding' ) }
sides={ paddingSides }
units={ units }
resetToInitialValues
/>
) }
{ showMarginControl && (
<BoxControl
values={ marginValues }
onChange={ setMarginValues }
label={ __( 'Margin' ) }
sides={ marginSides }
units={ units }
resetToInitialValues
/>
) }
</PanelBody>
);
}