Skip to content

Commit

Permalink
Dimensions Panel: Add new ToolsPanel component and update spacing sup…
Browse files Browse the repository at this point in the history
…ports (#32392)

- Adds new ToolsPanel components
- Uses the new components to refactor spacing block supports into a "Dimensions" panel.
  • Loading branch information
aaronrobertshaw committed Aug 10, 2021
1 parent 77f5da7 commit 5a610d4
Show file tree
Hide file tree
Showing 29 changed files with 1,378 additions and 133 deletions.
18 changes: 18 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1277,6 +1277,24 @@
"markdown_source": "../packages/components/src/toolbar/README.md",
"parent": "components"
},
{
"title": "ToolsPanelHeader",
"slug": "tools-panel-header",
"markdown_source": "../packages/components/src/tools-panel/tools-panel-header/README.md",
"parent": "components"
},
{
"title": "ToolsPanelItem",
"slug": "tools-panel-item",
"markdown_source": "../packages/components/src/tools-panel/tools-panel-item/README.md",
"parent": "components"
},
{
"title": "ToolsPanel",
"slug": "tools-panel",
"markdown_source": "../packages/components/src/tools-panel/tools-panel/README.md",
"parent": "components"
},
{
"title": "Tooltip",
"slug": "tooltip",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* Spacing block support flag.
* Dimensions block support flag.
*
* @package gutenberg
*/
Expand All @@ -10,21 +10,43 @@
*
* @param WP_Block_Type $block_type Block Type.
*/
function gutenberg_register_spacing_support( $block_type ) {
$has_spacing_support = gutenberg_block_has_support( $block_type, array( 'spacing' ), false );

function gutenberg_register_dimensions_support( $block_type ) {
// Setup attributes and styles within that if needed.
if ( ! $block_type->attributes ) {
$block_type->attributes = array();
}

if ( $has_spacing_support && ! array_key_exists( 'style', $block_type->attributes ) ) {
// Check for existing style attribute definition e.g. from block.json.
if ( array_key_exists( 'style', $block_type->attributes ) ) {
return;
}

$has_spacing_support = gutenberg_block_has_support( $block_type, array( 'spacing' ), false );
// Future block supports such as height & width will be added here.

if ( $has_spacing_support ) {
$block_type->attributes['style'] = array(
'type' => 'object',
);
}
}

/**
* Add CSS classes for block dimensions to the incoming attributes array.
* This will be applied to the block markup in the front-end.
*
* @param WP_Block_Type $block_type Block Type.
* @param array $block_attributes Block attributes.
*
* @return array Block spacing CSS classes and inline styles.
*/
function gutenberg_apply_dimensions_support( $block_type, $block_attributes ) {
$spacing_styles = gutenberg_apply_spacing_support( $block_type, $block_attributes );
// Future block supports such as height and width will be added here.

return $spacing_styles;
}

/**
* Add CSS classes for block spacing to the incoming attributes array.
* This will be applied to the block markup in the front-end.
Expand Down Expand Up @@ -88,9 +110,9 @@ function gutenberg_skip_spacing_serialization( $block_type ) {

// Register the block support.
WP_Block_Supports::get_instance()->register(
'spacing',
'dimensions',
array(
'register_attribute' => 'gutenberg_register_spacing_support',
'apply' => 'gutenberg_apply_spacing_support',
'register_attribute' => 'gutenberg_register_dimensions_support',
'apply' => 'gutenberg_apply_dimensions_support',
)
);
2 changes: 1 addition & 1 deletion lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,5 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/block-supports/custom-classname.php';
require __DIR__ . '/block-supports/border.php';
require __DIR__ . '/block-supports/layout.php';
require __DIR__ . '/block-supports/spacing.php';
require __DIR__ . '/block-supports/dimensions.php';
require __DIR__ . '/block-supports/duotone.php';
154 changes: 154 additions & 0 deletions packages/block-editor/src/hooks/dimensions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/**
* WordPress dependencies
*/
import {
__experimentalToolsPanel as ToolsPanel,
__experimentalToolsPanelItem as ToolsPanelItem,
} from '@wordpress/components';
import { Platform } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { getBlockSupport } from '@wordpress/blocks';

/**
* Internal dependencies
*/
import InspectorControls from '../components/inspector-controls';
import {
MarginEdit,
hasMarginSupport,
hasMarginValue,
resetMargin,
useIsMarginDisabled,
} from './margin';
import {
PaddingEdit,
hasPaddingSupport,
hasPaddingValue,
resetPadding,
useIsPaddingDisabled,
} from './padding';
import { cleanEmptyObject } from './utils';

export const SPACING_SUPPORT_KEY = 'spacing';

/**
* Inspector controls for dimensions support.
*
* @param {Object} props Block props.
*
* @return {WPElement} Inspector controls for spacing support features.
*/
export function DimensionsPanel( props ) {
const isPaddingDisabled = useIsPaddingDisabled( props );
const isMarginDisabled = useIsMarginDisabled( props );
const isDisabled = useIsDimensionsDisabled( props );
const isSupported = hasDimensionsSupport( props.name );

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

const defaultSpacingControls = getBlockSupport( props.name, [
SPACING_SUPPORT_KEY,
'__experimentalDefaultControls',
] );

// Callback to reset all block support attributes controlled via this panel.
const resetAll = () => {
const { style } = props.attributes;

props.setAttributes( {
style: cleanEmptyObject( {
...style,
spacing: {
...style?.spacing,
margin: undefined,
padding: undefined,
},
} ),
} );
};

return (
<InspectorControls key="dimensions">
<ToolsPanel
label={ __( 'Dimensions options' ) }
header={ __( 'Dimensions' ) }
resetAll={ resetAll }
>
{ ! isPaddingDisabled && (
<ToolsPanelItem
hasValue={ () => hasPaddingValue( props ) }
label={ __( 'Padding' ) }
onDeselect={ () => resetPadding( props ) }
isShownByDefault={ defaultSpacingControls?.padding }
>
<PaddingEdit { ...props } />
</ToolsPanelItem>
) }
{ ! isMarginDisabled && (
<ToolsPanelItem
hasValue={ () => hasMarginValue( props ) }
label={ __( 'Margin' ) }
onDeselect={ () => resetMargin( props ) }
isShownByDefault={ defaultSpacingControls?.margin }
>
<MarginEdit { ...props } />
</ToolsPanelItem>
) }
</ToolsPanel>
</InspectorControls>
);
}

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

return hasPaddingSupport( blockName ) || hasMarginSupport( blockName );
}

/**
* Determines whether dimensions support has been disabled.
*
* @param {Object} props Block properties.
*
* @return {boolean} If spacing support is completely disabled.
*/
const useIsDimensionsDisabled = ( 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 );

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

return support[ feature ];
}
2 changes: 1 addition & 1 deletion packages/block-editor/src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import './font-size';
import './border-color';
import './layout';

export { useCustomSides } from './spacing';
export { useCustomSides } from './dimensions';
export { getBorderClassesAndStyles, useBorderProps } from './use-border-props';
export { getColorClassesAndStyles, useColorProps } from './use-color-props';
export { getSpacingClassesAndStyles } from './use-spacing-props';
35 changes: 34 additions & 1 deletion packages/block-editor/src/hooks/margin.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
* Internal dependencies
*/
import useSetting from '../components/use-setting';
import { SPACING_SUPPORT_KEY, useCustomSides } from './spacing';
import { SPACING_SUPPORT_KEY, useCustomSides } from './dimensions';
import { cleanEmptyObject } from './utils';

/**
Expand All @@ -28,6 +28,38 @@ export function hasMarginSupport( blockType ) {
return !! ( true === support || support?.margin );
}

/**
* Checks if there is a current value in the margin block support attributes.
*
* @param {Object} props Block props.
* @return {boolean} Whether or not the block has a margin value set.
*/
export function hasMarginValue( props ) {
return props.attributes.style?.spacing?.margin !== undefined;
}

/**
* Resets the margin block support attributes. This can be used when disabling
* the margin support controls for a block via a `ToolsPanel`.
*
* @param {Object} props Block props.
* @param {Object} props.attributes Block's attributes.
* @param {Object} props.setAttributes Function to set block's attributes.
*/
export function resetMargin( { attributes = {}, setAttributes } ) {
const { style } = attributes;

setAttributes( {
style: cleanEmptyObject( {
...style,
spacing: {
...style?.spacing,
margin: undefined,
},
} ),
} );
}

/**
* Custom hook that checks if margin settings have been disabled.
*
Expand Down Expand Up @@ -106,6 +138,7 @@ export function MarginEdit( props ) {
label={ __( 'Margin' ) }
sides={ sides }
units={ units }
allowReset={ false }
/>
</>
),
Expand Down
35 changes: 34 additions & 1 deletion packages/block-editor/src/hooks/padding.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
* Internal dependencies
*/
import useSetting from '../components/use-setting';
import { SPACING_SUPPORT_KEY, useCustomSides } from './spacing';
import { SPACING_SUPPORT_KEY, useCustomSides } from './dimensions';
import { cleanEmptyObject } from './utils';

/**
Expand All @@ -28,6 +28,38 @@ export function hasPaddingSupport( blockType ) {
return !! ( true === support || support?.padding );
}

/**
* Checks if there is a current value in the padding block support attributes.
*
* @param {Object} props Block props.
* @return {boolean} Whether or not the block has a padding value set.
*/
export function hasPaddingValue( props ) {
return props.attributes.style?.spacing?.padding !== undefined;
}

/**
* Resets the padding block support attributes. This can be used when disabling
* the padding support controls for a block via a `ToolsPanel`.
*
* @param {Object} props Block props.
* @param {Object} props.attributes Block's attributes.
* @param {Object} props.setAttributes Function to set block's attributes.
*/
export function resetPadding( { attributes = {}, setAttributes } ) {
const { style } = attributes;

setAttributes( {
style: cleanEmptyObject( {
...style,
spacing: {
...style?.spacing,
padding: undefined,
},
} ),
} );
}

/**
* Custom hook that checks if padding settings have been disabled.
*
Expand Down Expand Up @@ -106,6 +138,7 @@ export function PaddingEdit( props ) {
label={ __( 'Padding' ) }
sides={ sides }
units={ units }
allowReset={ false }
/>
</>
),
Expand Down
Loading

0 comments on commit 5a610d4

Please sign in to comment.