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 editor: hooks: subscribe only to relevant attributes #56783

Merged
merged 5 commits into from
Dec 5, 2023
Merged
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
48 changes: 25 additions & 23 deletions packages/block-editor/src/hooks/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { Platform, useCallback, useRef } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import { getFilename } from '@wordpress/url';
import { pure } from '@wordpress/compose';

/**
* Internal dependencies
Expand All @@ -41,13 +42,13 @@ export const IMAGE_BACKGROUND_TYPE = 'image';
* Checks if there is a current value in the background image block support
* attributes.
*
* @param {Object} props Block props.
* @param {Object} style Style attribute.
* @return {boolean} Whether or not the block has a background image value set.
*/
export function hasBackgroundImageValue( props ) {
export function hasBackgroundImageValue( style ) {
const hasValue =
!! props.attributes.style?.background?.backgroundImage?.id ||
!! props.attributes.style?.background?.backgroundImage?.url;
!! style?.background?.backgroundImage?.id ||
!! style?.background?.backgroundImage?.url;

return hasValue;
}
Expand Down Expand Up @@ -82,13 +83,10 @@ export function hasBackgroundSupport( blockName, feature = 'any' ) {
* Resets the background image block support attributes. This can be used when disabling
* the background image 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.
* @param {Object} style Style attribute.
* @param {Function} setAttributes Function to set block's attributes.
*/
export function resetBackgroundImage( { attributes = {}, setAttributes } ) {
const { style = {} } = attributes;

export function resetBackgroundImage( style = {}, setAttributes ) {
setAttributes( {
style: cleanEmptyObject( {
...style,
Expand Down Expand Up @@ -145,11 +143,13 @@ function InspectorImagePreview( { label, filename, url: imgUrl } ) {
);
}

function BackgroundImagePanelItem( props ) {
const { attributes, clientId, setAttributes } = props;

const { id, title, url } =
attributes.style?.background?.backgroundImage || {};
function BackgroundImagePanelItem( { clientId, setAttributes } ) {
const style = useSelect(
( select ) =>
select( blockEditorStore ).getBlockAttributes( clientId )?.style,
[ clientId ]
);
const { id, title, url } = style?.background?.backgroundImage || {};

const replaceContainerRef = useRef();

Expand All @@ -167,9 +167,9 @@ function BackgroundImagePanelItem( props ) {
const onSelectMedia = ( media ) => {
if ( ! media || ! media.url ) {
const newStyle = {
...attributes.style,
...style,
background: {
...attributes.style?.background,
...style?.background,
backgroundImage: undefined,
},
};
Expand Down Expand Up @@ -201,9 +201,9 @@ function BackgroundImagePanelItem( props ) {
}

const newStyle = {
...attributes.style,
...style,
background: {
...attributes.style?.background,
...style?.background,
backgroundImage: {
url: media.url,
id: media.id,
Expand Down Expand Up @@ -244,14 +244,14 @@ function BackgroundImagePanelItem( props ) {
};
}, [] );

const hasValue = hasBackgroundImageValue( props );
const hasValue = hasBackgroundImageValue( style );

return (
<ToolsPanelItem
className="single-column"
hasValue={ () => hasValue }
label={ __( 'Background image' ) }
onDeselect={ () => resetBackgroundImage( props ) }
onDeselect={ () => resetBackgroundImage( style, setAttributes ) }
isShownByDefault={ true }
resetAllFilter={ resetAllFilter }
panelId={ clientId }
Expand Down Expand Up @@ -286,7 +286,7 @@ function BackgroundImagePanelItem( props ) {
// closed and focus is redirected to the dropdown toggle button.
toggleButton?.focus();
toggleButton?.click();
resetBackgroundImage( props );
resetBackgroundImage( style, setAttributes );
} }
>
{ __( 'Reset ' ) }
Expand All @@ -302,7 +302,7 @@ function BackgroundImagePanelItem( props ) {
);
}

export function BackgroundImagePanel( props ) {
function BackgroundImagePanelPure( props ) {
const [ backgroundImage ] = useSettings( 'background.backgroundImage' );
if (
! backgroundImage ||
Expand All @@ -317,3 +317,5 @@ export function BackgroundImagePanel( props ) {
</InspectorControls>
);
}

export const BackgroundImagePanel = pure( BackgroundImagePanelPure );
24 changes: 15 additions & 9 deletions packages/block-editor/src/hooks/border.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import classnames from 'classnames';
*/
import { getBlockSupport } from '@wordpress/blocks';
import { __experimentalHasSplitBorders as hasSplitBorders } from '@wordpress/components';
import { createHigherOrderComponent } from '@wordpress/compose';
import { createHigherOrderComponent, pure } from '@wordpress/compose';
import { Platform, useCallback, useMemo } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -27,6 +28,7 @@ import {
useHasBorderPanel,
BorderPanel as StylesBorderPanel,
} from '../components/global-styles';
import { store as blockEditorStore } from '../store';

export const BORDER_SUPPORT_KEY = '__experimentalBorder';

Expand Down Expand Up @@ -135,16 +137,18 @@ function BordersInspectorControl( { children, resetAllFilter } ) {
);
}

export function BorderPanel( props ) {
const { clientId, name, attributes, setAttributes } = props;
function BorderPanelPure( { clientId, name, setAttributes } ) {
const settings = useBlockSettings( name );
const isEnabled = useHasBorderPanel( settings );
function selector( select ) {
const { style, borderColor } =
select( blockEditorStore ).getBlockAttributes( clientId ) || {};
return { style, borderColor };
}
const { style, borderColor } = useSelect( selector, [ clientId ] );
const value = useMemo( () => {
return attributesToStyle( {
style: attributes.style,
borderColor: attributes.borderColor,
} );
}, [ attributes.style, attributes.borderColor ] );
return attributesToStyle( { style, borderColor } );
}, [ style, borderColor ] );

const onChange = ( newStyle ) => {
setAttributes( styleToAttributes( newStyle ) );
Expand All @@ -154,7 +158,7 @@ export function BorderPanel( props ) {
return null;
}

const defaultControls = getBlockSupport( props.name, [
const defaultControls = getBlockSupport( name, [
BORDER_SUPPORT_KEY,
'__experimentalDefaultControls',
] );
Expand All @@ -171,6 +175,8 @@ export function BorderPanel( props ) {
);
}

export const BorderPanel = pure( BorderPanelPure );

/**
* Determine whether there is block support for border properties.
*
Expand Down
39 changes: 23 additions & 16 deletions packages/block-editor/src/hooks/color.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import classnames from 'classnames';
import { addFilter } from '@wordpress/hooks';
import { getBlockSupport } from '@wordpress/blocks';
import { useMemo, Platform, useCallback } from '@wordpress/element';
import { createHigherOrderComponent } from '@wordpress/compose';
import { createHigherOrderComponent, pure } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -32,6 +33,7 @@ import {
default as StylesColorPanel,
} from '../components/global-styles/color-panel';
import BlockColorContrastChecker from './contrast-checker';
import { store as blockEditorStore } from '../store';

export const COLOR_SUPPORT_KEY = 'color';

Expand Down Expand Up @@ -289,23 +291,26 @@ function ColorInspectorControl( { children, resetAllFilter } ) {
);
}

export function ColorEdit( props ) {
const { clientId, name, attributes, setAttributes } = props;
function ColorEditPure( { clientId, name, setAttributes } ) {
const settings = useBlockSettings( name );
const isEnabled = useHasColorPanel( settings );
function selector( select ) {
const { style, textColor, backgroundColor, gradient } =
select( blockEditorStore ).getBlockAttributes( clientId ) || {};
return { style, textColor, backgroundColor, gradient };
}
const { style, textColor, backgroundColor, gradient } = useSelect(
selector,
[ clientId ]
);
const value = useMemo( () => {
return attributesToStyle( {
style: attributes.style,
textColor: attributes.textColor,
backgroundColor: attributes.backgroundColor,
gradient: attributes.gradient,
style,
textColor,
backgroundColor,
gradient,
} );
}, [
attributes.style,
attributes.textColor,
attributes.backgroundColor,
attributes.gradient,
] );
}, [ style, textColor, backgroundColor, gradient ] );

const onChange = ( newStyle ) => {
setAttributes( styleToAttributes( newStyle ) );
Expand All @@ -315,7 +320,7 @@ export function ColorEdit( props ) {
return null;
}

const defaultControls = getBlockSupport( props.name, [
const defaultControls = getBlockSupport( name, [
COLOR_SUPPORT_KEY,
'__experimentalDefaultControls',
] );
Expand All @@ -328,7 +333,7 @@ export function ColorEdit( props ) {
// Deactivating it requires `enableContrastChecker` to have
// an explicit value of `false`.
false !==
getBlockSupport( props.name, [
getBlockSupport( name, [
COLOR_SUPPORT_KEY,
'enableContrastChecker',
] );
Expand All @@ -343,7 +348,7 @@ export function ColorEdit( props ) {
defaultControls={ defaultControls }
enableContrastChecker={
false !==
getBlockSupport( props.name, [
getBlockSupport( name, [
COLOR_SUPPORT_KEY,
'enableContrastChecker',
] )
Expand All @@ -356,6 +361,8 @@ export function ColorEdit( props ) {
);
}

export const ColorEdit = pure( ColorEditPure );

/**
* This adds inline styles for color palette colors.
* Ideally, this is not needed and themes should load their palettes on the editor.
Expand Down
35 changes: 21 additions & 14 deletions packages/block-editor/src/hooks/dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
* WordPress dependencies
*/
import { useState, useEffect, useCallback } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
import { useDispatch, useSelect } from '@wordpress/data';
import { getBlockSupport } from '@wordpress/blocks';
import deprecated from '@wordpress/deprecated';
import { pure } from '@wordpress/compose';

/**
* Internal dependencies
Expand Down Expand Up @@ -65,17 +66,19 @@ function DimensionsInspectorControl( { children, resetAllFilter } ) {
);
}

export function DimensionsPanel( props ) {
const {
clientId,
name,
attributes,
setAttributes,
__unstableParentLayout,
} = props;
function DimensionsPanelPure( {
clientId,
name,
setAttributes,
__unstableParentLayout,
} ) {
const settings = useBlockSettings( name, __unstableParentLayout );
const isEnabled = useHasDimensionsPanel( settings );
const value = attributes.style;
const value = useSelect(
( select ) =>
select( blockEditorStore ).getBlockAttributes( clientId )?.style,
[ clientId ]
);
const [ visualizedProperty, setVisualizedProperty ] = useVisualizer();
const onChange = ( newStyle ) => {
setAttributes( {
Expand All @@ -87,11 +90,11 @@ export function DimensionsPanel( props ) {
return null;
}

const defaultDimensionsControls = getBlockSupport( props.name, [
const defaultDimensionsControls = getBlockSupport( name, [
DIMENSIONS_SUPPORT_KEY,
'__experimentalDefaultControls',
] );
const defaultSpacingControls = getBlockSupport( props.name, [
const defaultSpacingControls = getBlockSupport( name, [
SPACING_SUPPORT_KEY,
'__experimentalDefaultControls',
] );
Expand All @@ -114,19 +117,23 @@ export function DimensionsPanel( props ) {
{ !! settings?.spacing?.padding && (
<PaddingVisualizer
forceShow={ visualizedProperty === 'padding' }
{ ...props }
clientId={ clientId }
value={ value }
/>
) }
{ !! settings?.spacing?.margin && (
<MarginVisualizer
forceShow={ visualizedProperty === 'margin' }
{ ...props }
clientId={ clientId }
value={ value }
/>
) }
</>
);
}

export const DimensionsPanel = pure( DimensionsPanelPure );

/**
* @deprecated
*/
Expand Down
4 changes: 2 additions & 2 deletions packages/block-editor/src/hooks/padding.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ function getComputedCSS( element, property ) {
.getPropertyValue( property );
}

export function PaddingVisualizer( { clientId, attributes, forceShow } ) {
export function PaddingVisualizer( { clientId, value, forceShow } ) {
const blockElement = useBlockElement( clientId );
const [ style, setStyle ] = useState();

const padding = attributes?.style?.spacing?.padding;
const padding = value?.spacing?.padding;

useEffect( () => {
if (
Expand Down
Loading
Loading