Skip to content

Commit

Permalink
Add height dimensions block support
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed Aug 6, 2021
1 parent 8218467 commit 63e8027
Show file tree
Hide file tree
Showing 11 changed files with 295 additions and 25 deletions.
67 changes: 57 additions & 10 deletions lib/block-supports/dimensions.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ function gutenberg_register_dimensions_support( $block_type ) {
return;
}

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

if ( $has_spacing_support ) {
if ( $has_dimensions_support || $has_spacing_support ) {
$block_type->attributes['style'] = array(
'type' => 'object',
);
Expand All @@ -41,22 +41,53 @@ function gutenberg_register_dimensions_support( $block_type ) {
* @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.
$dimensions_styles = gutenberg_get_dimensions_styles( $block_type, $block_attributes );
$spacing_styles = gutenberg_get_spacing_styles( $block_type, $block_attributes );
$styles = $dimensions_styles . $spacing_styles;

return $spacing_styles;
return empty( $styles ) ? array() : array( 'style' => $styles );
}

/**
* Add CSS classes for block spacing to the incoming attributes array.
* Add inline styles 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.
* @return array Block dimensions inline styles.
*/
function gutenberg_apply_spacing_support( $block_type, $block_attributes ) {
function gutenberg_get_dimensions_styles( $block_type, $block_attributes ) {
if ( gutenberg_skip_dimensions_serialization( $block_type ) ) {
return array();
}

$has_height_support = gutenberg_block_has_support( $block_type, array( '__experimentalDimensions', 'height' ), false );
$styles = array();

if ( $has_height_support ) {
$height_value = _wp_array_get( $block_attributes, array( 'style', 'dimensions', 'height' ), null );

if ( null !== $height_value ) {
$styles[] = sprintf( 'height: %s;', $height_value );
}
}

// Width support to be added in near future.

return empty( $styles ) ? null : implode( ' ', $styles );
}

/**
* Add inline styles for block spacing 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 inline styles.
*/
function gutenberg_get_spacing_styles( $block_type, $block_attributes ) {
if ( gutenberg_skip_spacing_serialization( $block_type ) ) {
return array();
}
Expand Down Expand Up @@ -89,7 +120,23 @@ function gutenberg_apply_spacing_support( $block_type, $block_attributes ) {
}
}

return empty( $styles ) ? array() : array( 'style' => implode( ' ', $styles ) );
return empty( $styles ) ? null : implode( ' ', $styles );
}

/**
* Checks whether serialization of the current block's dimensions properties
* should occur.
*
* @param WP_Block_type $block_type Block type.
*
* @return boolean Whether to serialize dimensions support styles & classes.
*/
function gutenberg_skip_dimensions_serialization( $block_type ) {
$dimensions_support = _wp_array_get( $block_type->supports, array( '__experimentalDimensions' ), false );

return is_array( $dimensions_support ) &&
array_key_exists( '__experimentalSkipSerialization', $dimensions_support ) &&
$dimensions_support['__experimentalSkipSerialization'];
}

/**
Expand Down
7 changes: 7 additions & 0 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class WP_Theme_JSON_Gutenberg {
'gradient' => null,
'text' => null,
),
'dimensions' => array(
'height' => null,
),
'spacing' => array(
'margin' => null,
'padding' => null,
Expand Down Expand Up @@ -93,6 +96,9 @@ class WP_Theme_JSON_Gutenberg {
'palette' => null,
),
'custom' => null,
'dimensions' => array(
'customHeight' => null,
),
'layout' => array(
'contentSize' => null,
'wideSize' => null,
Expand Down Expand Up @@ -221,6 +227,7 @@ class WP_Theme_JSON_Gutenberg {
'font-size' => array( 'typography', 'fontSize' ),
'font-style' => array( 'typography', 'fontStyle' ),
'font-weight' => array( 'typography', 'fontWeight' ),
'height' => array( 'dimensions', 'height' ),
'letter-spacing' => array( 'typography', 'letterSpacing' ),
'line-height' => array( 'typography', 'lineHeight' ),
'margin' => array( 'spacing', 'margin' ),
Expand Down
3 changes: 3 additions & 0 deletions lib/experimental-default-theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@
}
]
},
"dimensions": {
"customHeight": false
},
"spacing": {
"customMargin": false,
"customPadding": false,
Expand Down
44 changes: 38 additions & 6 deletions packages/block-editor/src/hooks/dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ import { getBlockSupport } from '@wordpress/blocks';
* Internal dependencies
*/
import InspectorControls from '../components/inspector-controls';
import {
HeightEdit,
hasHeightSupport,
hasHeightValue,
resetHeight,
useIsHeightDisabled,
} from './height';
import {
MarginEdit,
hasMarginSupport,
Expand All @@ -29,25 +36,31 @@ import {
} from './padding';
import { cleanEmptyObject } from './utils';

export const DIMENSIONS_SUPPORT_KEY = '__experimentalDimensions';
export const SPACING_SUPPORT_KEY = 'spacing';

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

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

const defaultDimensionsControls = getBlockSupport( props.name, [
DIMENSIONS_SUPPORT_KEY,
'__experimentalDefaultControls',
] );

const defaultSpacingControls = getBlockSupport( props.name, [
SPACING_SUPPORT_KEY,
'__experimentalDefaultControls',
Expand All @@ -60,6 +73,10 @@ export function DimensionsPanel( props ) {
props.setAttributes( {
style: cleanEmptyObject( {
...style,
dimensions: {
...style?.dimensions,
height: undefined,
},
spacing: {
...style?.spacing,
margin: undefined,
Expand All @@ -76,6 +93,17 @@ export function DimensionsPanel( props ) {
header={ __( 'Dimensions' ) }
resetAll={ resetAll }
>
{ ! isHeightDisabled && (
<ToolsPanelItem
className="single-column"
hasValue={ () => hasHeightValue( props ) }
label={ __( 'Height' ) }
onDeselect={ () => resetHeight( props ) }
isShownByDefault={ defaultDimensionsControls?.height }
>
<HeightEdit { ...props } />
</ToolsPanelItem>
) }
{ ! isPaddingDisabled && (
<ToolsPanelItem
hasValue={ () => hasPaddingValue( props ) }
Expand Down Expand Up @@ -113,21 +141,25 @@ export function hasDimensionsSupport( blockName ) {
return false;
}

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

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

return paddingDisabled && marginDisabled;
return heightDisabled && paddingDisabled && marginDisabled;
};

/**
Expand Down
121 changes: 121 additions & 0 deletions packages/block-editor/src/hooks/height.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/**
* WordPress dependencies
*/
import { getBlockSupport } from '@wordpress/blocks';
import {
__experimentalUseCustomUnits as useCustomUnits,
__experimentalUnitControl as UnitControl,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import useSetting from '../components/use-setting';
import { DIMENSIONS_SUPPORT_KEY } from './dimensions';
import { cleanEmptyObject } from './utils';

/**
* Determines if there is height support.
*
* @param {string|Object} blockType Block name or Block Type object.
* @return {boolean} Whether there is support.
*/
export function hasHeightSupport( blockType ) {
const support = getBlockSupport( blockType, DIMENSIONS_SUPPORT_KEY );
return !! ( true === support || support?.height );
}

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

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

setAttributes( {
style: {
...style,
dimensions: {
...style?.dimensions,
height: undefined,
},
},
} );
}

/**
* Custom hook that checks if height controls have been disabled.
*
* @param {string} name The name of the block.
* @return {boolean} Whether height control is disabled.
*/
export function useIsHeightDisabled( { name: blockName } = {} ) {
const isDisabled = ! useSetting( 'dimensions.customHeight' );
return ! hasHeightSupport( blockName ) || isDisabled;
}

/**
* Inspector control panel containing the height related configuration.
*
* @param {Object} props Block props.
* @return {WPElement} Edit component for height.
*/
export function HeightEdit( props ) {
const {
attributes: { style },
setAttributes,
} = props;

const units = useCustomUnits( {
availableUnits: useSetting( 'dimensions.units' ) || [
'%',
'px',
'em',
'rem',
'vh',
'vw',
],
} );

if ( useIsHeightDisabled( props ) ) {
return null;
}

const onChange = ( next ) => {
const newStyle = {
...style,
dimensions: {
...style?.dimensions,
height: next,
},
};

setAttributes( { style: cleanEmptyObject( newStyle ) } );
};

return (
<UnitControl
label={ __( 'Height' ) }
value={ style?.dimensions?.height }
units={ units }
onChange={ onChange }
min={ 0 }
/>
);
}
12 changes: 10 additions & 2 deletions packages/block-editor/src/hooks/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,18 @@ import {
TYPOGRAPHY_SUPPORT_KEY,
TYPOGRAPHY_SUPPORT_KEYS,
} from './typography';
import { SPACING_SUPPORT_KEY, DimensionsPanel } from './dimensions';
import {
DIMENSIONS_SUPPORT_KEY,
SPACING_SUPPORT_KEY,
DimensionsPanel,
} from './dimensions';
import useDisplayBlockControls from '../components/use-display-block-controls';

const styleSupportKeys = [
...TYPOGRAPHY_SUPPORT_KEYS,
BORDER_SUPPORT_KEY,
COLOR_SUPPORT_KEY,
DIMENSIONS_SUPPORT_KEY,
SPACING_SUPPORT_KEY,
];

Expand Down Expand Up @@ -152,8 +157,11 @@ const skipSerializationPaths = {
[ `${ TYPOGRAPHY_SUPPORT_KEY }.__experimentalSkipSerialization` ]: [
TYPOGRAPHY_SUPPORT_KEY,
],
[ `${ DIMENSIONS_SUPPORT_KEY }.__experimentalSkipSerialization` ]: [
DIMENSIONS_SUPPORT_KEY,
],
[ `${ SPACING_SUPPORT_KEY }.__experimentalSkipSerialization` ]: [
'spacing',
SPACING_SUPPORT_KEY,
],
};

Expand Down
Loading

0 comments on commit 63e8027

Please sign in to comment.