diff --git a/packages/block-editor/src/components/block-controls/hook.js b/packages/block-editor/src/components/block-controls/hook.js
index 18a38e245e58a..e3f69c8bec3b2 100644
--- a/packages/block-editor/src/components/block-controls/hook.js
+++ b/packages/block-editor/src/components/block-controls/hook.js
@@ -1,45 +1,19 @@
/**
* WordPress dependencies
*/
-import { store as blocksStore } from '@wordpress/blocks';
-import { useSelect } from '@wordpress/data';
/**
* Internal dependencies
*/
import groups from './groups';
-import { store as blockEditorStore } from '../../store';
-import { useBlockEditContext } from '../block-edit/context';
import useDisplayBlockControls from '../use-display-block-controls';
export default function useBlockControlsFill( group, shareWithChildBlocks ) {
- const isDisplayed = useDisplayBlockControls();
- const { clientId } = useBlockEditContext();
- const isParentDisplayed = useSelect(
- ( select ) => {
- if ( ! shareWithChildBlocks ) {
- return false;
- }
-
- const { getBlockName, hasSelectedInnerBlock } =
- select( blockEditorStore );
- const { hasBlockSupport } = select( blocksStore );
-
- return (
- hasBlockSupport(
- getBlockName( clientId ),
- '__experimentalExposeControlsToChildren',
- false
- ) && hasSelectedInnerBlock( clientId )
- );
- },
- [ shareWithChildBlocks, clientId ]
- );
-
+ const { isDisplayed, isParentDisplayed } = useDisplayBlockControls();
if ( isDisplayed ) {
return groups[ group ]?.Fill;
}
- if ( isParentDisplayed ) {
+ if ( isParentDisplayed && shareWithChildBlocks ) {
return groups.parent.Fill;
}
return null;
diff --git a/packages/block-editor/src/components/block-info-slot-fill/index.js b/packages/block-editor/src/components/block-info-slot-fill/index.js
index db7919b6ef5ea..8e16757f3ebbc 100644
--- a/packages/block-editor/src/components/block-info-slot-fill/index.js
+++ b/packages/block-editor/src/components/block-info-slot-fill/index.js
@@ -13,7 +13,7 @@ const { createPrivateSlotFill } = unlock( componentsPrivateApis );
const { Fill, Slot } = createPrivateSlotFill( 'BlockInformation' );
const BlockInfo = ( props ) => {
- const isDisplayed = useDisplayBlockControls();
+ const { isDisplayed } = useDisplayBlockControls();
if ( ! isDisplayed ) {
return null;
}
diff --git a/packages/block-editor/src/components/inspector-controls/fill.js b/packages/block-editor/src/components/inspector-controls/fill.js
index f0640a9d31ddc..fdb0d44f0eccb 100644
--- a/packages/block-editor/src/components/inspector-controls/fill.js
+++ b/packages/block-editor/src/components/inspector-controls/fill.js
@@ -33,7 +33,7 @@ export default function InspectorControlsFill( {
group = __experimentalGroup;
}
- const isDisplayed = useDisplayBlockControls();
+ const { isDisplayed } = useDisplayBlockControls();
const Fill = groups[ group ]?.Fill;
if ( ! Fill ) {
warning( `Unknown InspectorControls group "${ group }" provided.` );
diff --git a/packages/block-editor/src/components/inspector-controls/fill.native.js b/packages/block-editor/src/components/inspector-controls/fill.native.js
index d38d865cd15cc..f1ee5a14cd18e 100644
--- a/packages/block-editor/src/components/inspector-controls/fill.native.js
+++ b/packages/block-editor/src/components/inspector-controls/fill.native.js
@@ -35,7 +35,7 @@ export default function InspectorControlsFill( {
);
group = __experimentalGroup;
}
- const isDisplayed = useDisplayBlockControls();
+ const { isDisplayed } = useDisplayBlockControls();
const Fill = groups[ group ]?.Fill;
if ( ! Fill ) {
diff --git a/packages/block-editor/src/components/use-display-block-controls/index.js b/packages/block-editor/src/components/use-display-block-controls/index.js
index 605556f295b96..ef27479593a73 100644
--- a/packages/block-editor/src/components/use-display-block-controls/index.js
+++ b/packages/block-editor/src/components/use-display-block-controls/index.js
@@ -2,6 +2,7 @@
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
+import { store as blocksStore } from '@wordpress/blocks';
/**
* Internal dependencies
@@ -13,23 +14,28 @@ export default function useDisplayBlockControls() {
const { isSelected, clientId, name } = useBlockEditContext();
return useSelect(
( select ) => {
- if ( isSelected ) {
- return true;
- }
-
const {
getBlockName,
isFirstMultiSelectedBlock,
getMultiSelectedBlockClientIds,
+ hasSelectedInnerBlock,
} = select( blockEditorStore );
+ const { hasBlockSupport } = select( blocksStore );
- if ( isFirstMultiSelectedBlock( clientId ) ) {
- return getMultiSelectedBlockClientIds().every(
- ( id ) => getBlockName( id ) === name
- );
- }
-
- return false;
+ return {
+ isDisplayed:
+ isSelected ||
+ ( isFirstMultiSelectedBlock( clientId ) &&
+ getMultiSelectedBlockClientIds().every(
+ ( id ) => getBlockName( id ) === name
+ ) ),
+ isParentDisplayed:
+ hasBlockSupport(
+ getBlockName( clientId ),
+ '__experimentalExposeControlsToChildren',
+ false
+ ) && hasSelectedInnerBlock( clientId ),
+ };
},
[ clientId, isSelected, name ]
);
diff --git a/packages/block-editor/src/components/use-display-block-controls/index.native.js b/packages/block-editor/src/components/use-display-block-controls/index.native.js
index e8a198e1592e8..d865ed6d9d7b2 100644
--- a/packages/block-editor/src/components/use-display-block-controls/index.native.js
+++ b/packages/block-editor/src/components/use-display-block-controls/index.native.js
@@ -26,11 +26,7 @@ export default function useDisplayBlockControls() {
false
);
- if ( ! hideControls && isSelected ) {
- return true;
- }
-
- return false;
+ return { isDisplayed: ! hideControls && isSelected };
},
[ clientId, isSelected, name ]
);
diff --git a/packages/block-editor/src/hooks/align.js b/packages/block-editor/src/hooks/align.js
index 3b916d9577f1a..2019228cf2d3e 100644
--- a/packages/block-editor/src/hooks/align.js
+++ b/packages/block-editor/src/hooks/align.js
@@ -6,7 +6,7 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
-import { createHigherOrderComponent, pure } from '@wordpress/compose';
+import { createHigherOrderComponent } from '@wordpress/compose';
import { addFilter } from '@wordpress/hooks';
import {
getBlockSupport,
@@ -109,7 +109,7 @@ export function addAttribute( settings ) {
}
function BlockEditAlignmentToolbarControlsPure( {
- blockName,
+ name: blockName,
align,
setAttributes,
} ) {
@@ -152,45 +152,14 @@ function BlockEditAlignmentToolbarControlsPure( {
);
}
-// We don't want block controls to re-render when typing inside a block. `pure`
-// will prevent re-renders unless props change, so only pass the needed props
-// and not the whole attributes object.
-const BlockEditAlignmentToolbarControls = pure(
- BlockEditAlignmentToolbarControlsPure
-);
-
-/**
- * Override the default edit UI to include new toolbar controls for block
- * alignment, if block defines support.
- *
- * @param {Function} BlockEdit Original component.
- *
- * @return {Function} Wrapped component.
- */
-export const withAlignmentControls = createHigherOrderComponent(
- ( BlockEdit ) => ( props ) => {
- const hasAlignmentSupport = hasBlockSupport(
- props.name,
- 'align',
- false
- );
-
- return (
- <>
- { hasAlignmentSupport && (
-
- ) }
-
- >
- );
+export default {
+ shareWithChildBlocks: true,
+ edit: BlockEditAlignmentToolbarControlsPure,
+ attributeKeys: [ 'align' ],
+ hasSupport( name ) {
+ return hasBlockSupport( name, 'align', false );
},
- 'withAlignmentControls'
-);
+};
function BlockListBlockWithDataAlign( { block: BlockListBlock, props } ) {
const { name, attributes } = props;
@@ -273,11 +242,6 @@ addFilter(
'core/editor/align/with-data-align',
withDataAlign
);
-addFilter(
- 'editor.BlockEdit',
- 'core/editor/align/with-toolbar-controls',
- withAlignmentControls
-);
addFilter(
'blocks.getSaveContent.extraProps',
'core/editor/align/addAssignedAlign',
diff --git a/packages/block-editor/src/hooks/align.native.js b/packages/block-editor/src/hooks/align.native.js
index 1bf375b654ad4..7a229e79870a8 100644
--- a/packages/block-editor/src/hooks/align.native.js
+++ b/packages/block-editor/src/hooks/align.native.js
@@ -8,6 +8,7 @@ import { WIDE_ALIGNMENTS } from '@wordpress/components';
const ALIGNMENTS = [ 'left', 'center', 'right' ];
export * from './align.js';
+export { default } from './align.js';
// Used to filter out blocks that don't support wide/full alignment on mobile
addFilter(
diff --git a/packages/block-editor/src/hooks/anchor.js b/packages/block-editor/src/hooks/anchor.js
index 9902ed479531c..882820678aa87 100644
--- a/packages/block-editor/src/hooks/anchor.js
+++ b/packages/block-editor/src/hooks/anchor.js
@@ -5,7 +5,6 @@ import { addFilter } from '@wordpress/hooks';
import { PanelBody, TextControl, ExternalLink } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { hasBlockSupport } from '@wordpress/blocks';
-import { createHigherOrderComponent, pure } from '@wordpress/compose';
import { Platform } from '@wordpress/element';
/**
@@ -52,7 +51,11 @@ export function addAttribute( settings ) {
return settings;
}
-function BlockEditAnchorControlPure( { blockName, anchor, setAttributes } ) {
+function BlockEditAnchorControlPure( {
+ name: blockName,
+ anchor,
+ setAttributes,
+} ) {
const blockEditingMode = useBlockEditingMode();
const isWeb = Platform.OS === 'web';
@@ -116,38 +119,13 @@ function BlockEditAnchorControlPure( { blockName, anchor, setAttributes } ) {
);
}
-// We don't want block controls to re-render when typing inside a block. `pure`
-// will prevent re-renders unless props change, so only pass the needed props
-// and not the whole attributes object.
-const BlockEditAnchorControl = pure( BlockEditAnchorControlPure );
-
-/**
- * Override the default edit UI to include a new block inspector control for
- * assigning the anchor ID, if block supports anchor.
- *
- * @param {Component} BlockEdit Original component.
- *
- * @return {Component} Wrapped component.
- */
-export const withAnchorControls = createHigherOrderComponent( ( BlockEdit ) => {
- return ( props ) => {
- return (
- <>
-
- { props.isSelected &&
- hasBlockSupport( props.name, 'anchor' ) && (
-
- ) }
- >
- );
- };
-}, 'withAnchorControls' );
+export default {
+ edit: BlockEditAnchorControlPure,
+ attributeKeys: [ 'anchor' ],
+ hasSupport( name ) {
+ return hasBlockSupport( name, 'anchor' );
+ },
+};
/**
* Override props assigned to save component to inject anchor ID, if block
@@ -169,11 +147,6 @@ export function addSaveProps( extraProps, blockType, attributes ) {
}
addFilter( 'blocks.registerBlockType', 'core/anchor/attribute', addAttribute );
-addFilter(
- 'editor.BlockEdit',
- 'core/editor/anchor/with-inspector-controls',
- withAnchorControls
-);
addFilter(
'blocks.getSaveContent.extraProps',
'core/editor/anchor/save-props',
diff --git a/packages/block-editor/src/hooks/block-hooks.js b/packages/block-editor/src/hooks/block-hooks.js
index 59c0e3c85486f..a1640c72f4b2b 100644
--- a/packages/block-editor/src/hooks/block-hooks.js
+++ b/packages/block-editor/src/hooks/block-hooks.js
@@ -2,14 +2,12 @@
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
-import { addFilter } from '@wordpress/hooks';
import { Fragment, useMemo } from '@wordpress/element';
import {
__experimentalHStack as HStack,
PanelBody,
ToggleControl,
} from '@wordpress/components';
-import { createHigherOrderComponent, pure } from '@wordpress/compose';
import { createBlock, store as blocksStore } from '@wordpress/blocks';
import { useDispatch, useSelect } from '@wordpress/data';
@@ -21,7 +19,7 @@ import { store as blockEditorStore } from '../store';
const EMPTY_OBJECT = {};
-function BlockHooksControlPure( props ) {
+function BlockHooksControlPure( { name, clientId } ) {
const blockTypes = useSelect(
( select ) => select( blocksStore ).getBlockTypes(),
[]
@@ -30,10 +28,9 @@ function BlockHooksControlPure( props ) {
const hookedBlocksForCurrentBlock = useMemo(
() =>
blockTypes?.filter(
- ( { blockHooks } ) =>
- blockHooks && props.blockName in blockHooks
+ ( { blockHooks } ) => blockHooks && name in blockHooks
),
- [ blockTypes, props.blockName ]
+ [ blockTypes, name ]
);
const { blockIndex, rootClientId, innerBlocksLength } = useSelect(
@@ -42,13 +39,12 @@ function BlockHooksControlPure( props ) {
select( blockEditorStore );
return {
- blockIndex: getBlockIndex( props.clientId ),
- innerBlocksLength: getBlock( props.clientId )?.innerBlocks
- ?.length,
- rootClientId: getBlockRootClientId( props.clientId ),
+ blockIndex: getBlockIndex( clientId ),
+ innerBlocksLength: getBlock( clientId )?.innerBlocks?.length,
+ rootClientId: getBlockRootClientId( clientId ),
};
},
- [ props.clientId ]
+ [ clientId ]
);
const hookedBlockClientIds = useSelect(
@@ -65,8 +61,7 @@ function BlockHooksControlPure( props ) {
return clientIds;
}
- const relativePosition =
- block?.blockHooks?.[ props.blockName ];
+ const relativePosition = block?.blockHooks?.[ name ];
let candidates;
switch ( relativePosition ) {
@@ -83,12 +78,12 @@ function BlockHooksControlPure( props ) {
// Any of the current block's child blocks (with the right block type) qualifies
// as a hooked first or last child block, as the block might've been automatically
// inserted and then moved around a bit by the user.
- candidates = getBlock( props.clientId ).innerBlocks;
+ candidates = getBlock( clientId ).innerBlocks;
break;
}
const hookedBlock = candidates?.find(
- ( { name } ) => name === block.name
+ ( candidate ) => name === candidate.name
);
// If the block exists in the designated location, we consider it hooked
@@ -118,12 +113,7 @@ function BlockHooksControlPure( props ) {
return EMPTY_OBJECT;
},
- [
- hookedBlocksForCurrentBlock,
- props.blockName,
- props.clientId,
- rootClientId,
- ]
+ [ hookedBlocksForCurrentBlock, name, clientId, rootClientId ]
);
const { insertBlock, removeBlock } = useDispatch( blockEditorStore );
@@ -169,7 +159,7 @@ function BlockHooksControlPure( props ) {
block,
// TODO: It'd be great if insertBlock() would accept negative indices for insertion.
relativePosition === 'first_child' ? 0 : innerBlocksLength,
- props.clientId, // Insert as a child of the current block.
+ clientId, // Insert as a child of the current block.
false
);
break;
@@ -207,9 +197,7 @@ function BlockHooksControlPure( props ) {
if ( ! checked ) {
// Create and insert block.
const relativePosition =
- block.blockHooks[
- props.blockName
- ];
+ block.blockHooks[ name ];
insertBlockIntoDesignatedLocation(
createBlock( block.name ),
relativePosition
@@ -218,11 +206,12 @@ function BlockHooksControlPure( props ) {
}
// Remove block.
- const clientId =
+ removeBlock(
hookedBlockClientIds[
block.name
- ];
- removeBlock( clientId, false );
+ ],
+ false
+ );
} }
/>
);
@@ -235,32 +224,9 @@ function BlockHooksControlPure( props ) {
);
}
-// We don't want block controls to re-render when typing inside a block. `pure`
-// will prevent re-renders unless props change, so only pass the needed props
-// and not the whole attributes object.
-const BlockHooksControl = pure( BlockHooksControlPure );
-
-export const withBlockHooksControls = createHigherOrderComponent(
- ( BlockEdit ) => {
- return ( props ) => {
- return (
- <>
-
- { props.isSelected && (
-
- ) }
- >
- );
- };
+export default {
+ edit: BlockHooksControlPure,
+ hasSupport() {
+ return true;
},
- 'withBlockHooksControls'
-);
-
-addFilter(
- 'editor.BlockEdit',
- 'core/editor/block-hooks/with-inspector-controls',
- withBlockHooksControls
-);
+};
diff --git a/packages/block-editor/src/hooks/block-renaming.js b/packages/block-editor/src/hooks/block-renaming.js
index 452be6e686dbf..26ada6ba73281 100644
--- a/packages/block-editor/src/hooks/block-renaming.js
+++ b/packages/block-editor/src/hooks/block-renaming.js
@@ -3,7 +3,6 @@
*/
import { addFilter } from '@wordpress/hooks';
import { hasBlockSupport } from '@wordpress/blocks';
-import { createHigherOrderComponent, pure } from '@wordpress/compose';
import { __ } from '@wordpress/i18n';
import { TextControl } from '@wordpress/components';
@@ -11,7 +10,6 @@ import { TextControl } from '@wordpress/components';
* Internal dependencies
*/
import { InspectorControls } from '../components';
-import { useBlockRename } from '../components/block-rename';
/**
* Filters registered block settings, adding an `__experimentalLabel` callback if one does not already exist.
@@ -47,13 +45,7 @@ export function addLabelCallback( settings ) {
return settings;
}
-function BlockRenameControlPure( { name, metadata, setAttributes } ) {
- const { canRename } = useBlockRename( name );
-
- if ( ! canRename ) {
- return null;
- }
-
+function BlockRenameControlPure( { metadata, setAttributes } ) {
return (
( props ) => {
- const { name, attributes, setAttributes, isSelected } = props;
- return (
- <>
- { isSelected && (
-
- ) }
-
- >
- );
+export default {
+ edit: BlockRenameControlPure,
+ attributeKeys: [ 'metadata' ],
+ hasSupport( name ) {
+ return hasBlockSupport( name, 'renaming', true );
},
- 'withToolbarControls'
-);
-
-addFilter(
- 'editor.BlockEdit',
- 'core/block-rename-ui/with-block-rename-control',
- withBlockRenameControl
-);
+};
addFilter(
'blocks.registerBlockType',
diff --git a/packages/block-editor/src/hooks/custom-class-name.js b/packages/block-editor/src/hooks/custom-class-name.js
index 8c0f58ddda682..331edd9ef214a 100644
--- a/packages/block-editor/src/hooks/custom-class-name.js
+++ b/packages/block-editor/src/hooks/custom-class-name.js
@@ -10,7 +10,6 @@ import { addFilter } from '@wordpress/hooks';
import { TextControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { hasBlockSupport } from '@wordpress/blocks';
-import { createHigherOrderComponent, pure } from '@wordpress/compose';
/**
* Internal dependencies
@@ -64,46 +63,13 @@ function CustomClassNameControlsPure( { className, setAttributes } ) {
);
}
-// We don't want block controls to re-render when typing inside a block. `pure`
-// will prevent re-renders unless props change, so only pass the needed props
-// and not the whole attributes object.
-const CustomClassNameControls = pure( CustomClassNameControlsPure );
-
-/**
- * Override the default edit UI to include a new block inspector control for
- * assigning the custom class name, if block supports custom class name.
- * The control is displayed within the Advanced panel in the block inspector.
- *
- * @param {Component} BlockEdit Original component.
- *
- * @return {Component} Wrapped component.
- */
-export const withCustomClassNameControls = createHigherOrderComponent(
- ( BlockEdit ) => {
- return ( props ) => {
- const hasCustomClassName = hasBlockSupport(
- props.name,
- 'customClassName',
- true
- );
-
- return (
- <>
-
- { hasCustomClassName && props.isSelected && (
-
- ) }
- >
- );
- };
+export default {
+ edit: CustomClassNameControlsPure,
+ attributeKeys: [ 'className' ],
+ hasSupport( name ) {
+ return hasBlockSupport( name, 'customClassName', true );
},
- 'withCustomClassNameControls'
-);
+};
/**
* Override props assigned to save component to inject the className, if block
@@ -174,11 +140,6 @@ addFilter(
'core/editor/custom-class-name/attribute',
addAttribute
);
-addFilter(
- 'editor.BlockEdit',
- 'core/editor/custom-class-name/with-inspector-controls',
- withCustomClassNameControls
-);
addFilter(
'blocks.getSaveContent.extraProps',
'core/editor/custom-class-name/save-props',
diff --git a/packages/block-editor/src/hooks/custom-fields.js b/packages/block-editor/src/hooks/custom-fields.js
index 19729d00ad61a..9b677933adc13 100644
--- a/packages/block-editor/src/hooks/custom-fields.js
+++ b/packages/block-editor/src/hooks/custom-fields.js
@@ -5,7 +5,6 @@ import { addFilter } from '@wordpress/hooks';
import { PanelBody, TextControl } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { hasBlockSupport } from '@wordpress/blocks';
-import { createHigherOrderComponent, pure } from '@wordpress/compose';
/**
* Internal dependencies
@@ -91,50 +90,18 @@ function CustomFieldsControlPure( { name, connections, setAttributes } ) {
);
}
-// We don't want block controls to re-render when typing inside a block. `pure`
-// will prevent re-renders unless props change, so only pass the needed props
-// and not the whole attributes object.
-const CustomFieldsControl = pure( CustomFieldsControlPure );
-
-/**
- * Override the default edit UI to include a new block inspector control for
- * assigning a connection to blocks that has support for connections.
- * Currently, only the `core/paragraph` block is supported and there is only a relation
- * between paragraph content and a custom field.
- *
- * @param {Component} BlockEdit Original component.
- *
- * @return {Component} Wrapped component.
- */
-const withCustomFieldsControls = createHigherOrderComponent( ( BlockEdit ) => {
- return ( props ) => {
- const hasCustomFieldsSupport = hasBlockSupport(
- props.name,
- '__experimentalConnections',
- false
- );
-
- // Check if the current block is a paragraph or image block.
- // Currently, only these two blocks are supported.
- if ( ! [ 'core/paragraph', 'core/image' ].includes( props.name ) ) {
- return ;
- }
-
+export default {
+ edit: CustomFieldsControlPure,
+ attributeKeys: [ 'connections' ],
+ hasSupport( name ) {
return (
- <>
-
- { hasCustomFieldsSupport && props.isSelected && (
-
- ) }
- >
+ hasBlockSupport( name, '__experimentalConnections', false ) &&
+ // Check if the current block is a paragraph or image block.
+ // Currently, only these two blocks are supported.
+ [ 'core/paragraph', 'core/image' ].includes( name )
);
- };
-}, 'withCustomFieldsControls' );
+ },
+};
if (
window.__experimentalConnections ||
@@ -146,10 +113,3 @@ if (
addAttribute
);
}
-if ( window.__experimentalConnections ) {
- addFilter(
- 'editor.BlockEdit',
- 'core/editor/connections/with-inspector-controls',
- withCustomFieldsControls
- );
-}
diff --git a/packages/block-editor/src/hooks/duotone.js b/packages/block-editor/src/hooks/duotone.js
index 6e18b44cef163..c0b76d12cb370 100644
--- a/packages/block-editor/src/hooks/duotone.js
+++ b/packages/block-editor/src/hooks/duotone.js
@@ -13,11 +13,7 @@ import {
getBlockType,
hasBlockSupport,
} from '@wordpress/blocks';
-import {
- createHigherOrderComponent,
- useInstanceId,
- pure,
-} from '@wordpress/compose';
+import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose';
import { addFilter } from '@wordpress/hooks';
import { useMemo, useEffect } from '@wordpress/element';
@@ -179,10 +175,14 @@ function DuotonePanelPure( { style, setAttributes, name } ) {
);
}
-// We don't want block controls to re-render when typing inside a block. `pure`
-// will prevent re-renders unless props change, so only pass the needed props
-// and not the whole attributes object.
-const DuotonePanel = pure( DuotonePanelPure );
+export default {
+ shareWithChildBlocks: true,
+ edit: DuotonePanelPure,
+ attributeKeys: [ 'style' ],
+ hasSupport( name ) {
+ return hasBlockSupport( name, 'filter.duotone' );
+ },
+};
/**
* Filters registered block settings, extending attributes to include
@@ -212,44 +212,6 @@ function addDuotoneAttributes( settings ) {
return settings;
}
-/**
- * Override the default edit UI to include toolbar controls for duotone if the
- * block supports duotone.
- *
- * @param {Function} BlockEdit Original component.
- *
- * @return {Function} Wrapped component.
- */
-const withDuotoneControls = createHigherOrderComponent(
- ( BlockEdit ) => ( props ) => {
- // Previous `color.__experimentalDuotone` support flag is migrated via
- // block_type_metadata_settings filter in `lib/block-supports/duotone.php`.
- const hasDuotoneSupport = hasBlockSupport(
- props.name,
- 'filter.duotone'
- );
-
- // CAUTION: code added before this line will be executed
- // for all blocks, not just those that support duotone. Code added
- // above this line should be carefully evaluated for its impact on
- // performance.
- return (
- <>
- { hasDuotoneSupport && (
-
- ) }
-
- >
- );
- },
- 'withDuotoneControls'
-);
-
function DuotoneStyles( {
clientId,
id: filterId,
@@ -438,11 +400,6 @@ addFilter(
'core/editor/duotone/add-attributes',
addDuotoneAttributes
);
-addFilter(
- 'editor.BlockEdit',
- 'core/editor/duotone/with-editor-controls',
- withDuotoneControls
-);
addFilter(
'editor.BlockListBlock',
'core/editor/duotone/with-styles',
diff --git a/packages/block-editor/src/hooks/index.js b/packages/block-editor/src/hooks/index.js
index c088216c0645c..6ae589dd672bf 100644
--- a/packages/block-editor/src/hooks/index.js
+++ b/packages/block-editor/src/hooks/index.js
@@ -1,27 +1,43 @@
/**
* Internal dependencies
*/
+import { createBlockEditFilter } from './utils';
import './compat';
-import './align';
+import align from './align';
import './lock';
-import './anchor';
+import anchor from './anchor';
import './aria-label';
-import './custom-class-name';
+import customClassName from './custom-class-name';
import './generated-class-name';
-import './style';
+import style from './style';
import './settings';
import './color';
-import './duotone';
+import duotone from './duotone';
import './font-family';
import './font-size';
import './border';
-import './position';
-import './layout';
+import position from './position';
+import layout from './layout';
import './content-lock-ui';
import './metadata';
-import './custom-fields';
-import './block-hooks';
-import './block-renaming';
+import customFields from './custom-fields';
+import blockHooks from './block-hooks';
+import blockRenaming from './block-renaming';
+
+createBlockEditFilter(
+ [
+ align,
+ anchor,
+ customClassName,
+ style,
+ duotone,
+ position,
+ layout,
+ window.__experimentalConnections ? customFields : null,
+ blockHooks,
+ blockRenaming,
+ ].filter( Boolean )
+);
export { useCustomSides } from './dimensions';
export { useLayoutClasses, useLayoutStyles } from './layout';
diff --git a/packages/block-editor/src/hooks/index.native.js b/packages/block-editor/src/hooks/index.native.js
index 42bda25bfe1cc..3f1a4473c1389 100644
--- a/packages/block-editor/src/hooks/index.native.js
+++ b/packages/block-editor/src/hooks/index.native.js
@@ -1,16 +1,19 @@
/**
* Internal dependencies
*/
+import { createBlockEditFilter } from './utils';
import './compat';
-import './align';
-import './anchor';
+import align from './align';
+import anchor from './anchor';
import './custom-class-name';
import './generated-class-name';
-import './style';
+import style from './style';
import './color';
import './font-size';
import './layout';
+createBlockEditFilter( [ align, anchor, style ] );
+
export { getBorderClassesAndStyles, useBorderProps } from './use-border-props';
export { getColorClassesAndStyles, useColorProps } from './use-color-props';
export { getSpacingClassesAndStyles } from './use-spacing-props';
diff --git a/packages/block-editor/src/hooks/layout.js b/packages/block-editor/src/hooks/layout.js
index 3ea5c56da8e77..46239e1de0703 100644
--- a/packages/block-editor/src/hooks/layout.js
+++ b/packages/block-editor/src/hooks/layout.js
@@ -6,11 +6,7 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
-import {
- createHigherOrderComponent,
- pure,
- useInstanceId,
-} from '@wordpress/compose';
+import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose';
import { addFilter } from '@wordpress/hooks';
import { getBlockSupport, hasBlockSupport } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
@@ -290,10 +286,14 @@ function LayoutPanelPure( { layout, setAttributes, name: blockName } ) {
);
}
-// We don't want block controls to re-render when typing inside a block. `pure`
-// will prevent re-renders unless props change, so only pass the needed props
-// and not the whole attributes object.
-const LayoutPanel = pure( LayoutPanelPure );
+export default {
+ shareWithChildBlocks: true,
+ edit: LayoutPanelPure,
+ attributeKeys: [ 'layout' ],
+ hasSupport( name ) {
+ return hasLayoutBlockSupport( name );
+ },
+};
function LayoutTypeSwitcher( { type, onChange } ) {
return (
@@ -336,33 +336,6 @@ export function addAttribute( settings ) {
return settings;
}
-/**
- * Override the default edit UI to include layout controls
- *
- * @param {Function} BlockEdit Original component.
- *
- * @return {Function} Wrapped component.
- */
-export const withLayoutControls = createHigherOrderComponent(
- ( BlockEdit ) => ( props ) => {
- const supportLayout = hasLayoutBlockSupport( props.name );
-
- return [
- supportLayout && (
-
- ),
- ,
- ];
- },
- 'withLayoutControls'
-);
-
function BlockWithLayoutStyles( { block: BlockListBlock, props } ) {
const { name, attributes } = props;
const id = useInstanceId( BlockListBlock );
@@ -516,8 +489,3 @@ addFilter(
'core/editor/layout/with-child-layout-styles',
withChildLayoutStyles
);
-addFilter(
- 'editor.BlockEdit',
- 'core/editor/layout/with-inspector-controls',
- withLayoutControls
-);
diff --git a/packages/block-editor/src/hooks/position.js b/packages/block-editor/src/hooks/position.js
index 32d4f6582969e..cdeb90822f0ac 100644
--- a/packages/block-editor/src/hooks/position.js
+++ b/packages/block-editor/src/hooks/position.js
@@ -12,11 +12,7 @@ import {
BaseControl,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
-import {
- createHigherOrderComponent,
- pure,
- useInstanceId,
-} from '@wordpress/compose';
+import { createHigherOrderComponent, useInstanceId } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
import { useMemo, Platform } from '@wordpress/element';
import { addFilter } from '@wordpress/hooks';
@@ -318,44 +314,19 @@ export function PositionPanelPure( {
} );
}
-// We don't want block controls to re-render when typing inside a block. `pure`
-// will prevent re-renders unless props change, so only pass the needed props
-// and not the whole attributes object.
-const PositionPanel = pure( PositionPanelPure );
-
-/**
- * Override the default edit UI to include position controls.
- *
- * @param {Function} BlockEdit Original component.
- *
- * @return {Function} Wrapped component.
- */
-export const withPositionControls = createHigherOrderComponent(
- ( BlockEdit ) => ( props ) => {
- const { name: blockName } = props;
- const positionSupport = hasBlockSupport(
- blockName,
- POSITION_SUPPORT_KEY
- );
+export default {
+ edit: function Edit( props ) {
const isPositionDisabled = useIsPositionDisabled( props );
- const showPositionControls = positionSupport && ! isPositionDisabled;
-
- return [
- showPositionControls && (
-
- ),
- ,
- ];
+ if ( isPositionDisabled ) {
+ return null;
+ }
+ return ;
},
- 'withPositionControls'
-);
+ attributeKeys: [ 'style' ],
+ hasSupport( name ) {
+ return hasBlockSupport( name, POSITION_SUPPORT_KEY );
+ },
+};
/**
* Override the default block element to add the position styles.
@@ -411,8 +382,3 @@ addFilter(
'core/editor/position/with-position-styles',
withPositionStyles
);
-addFilter(
- 'editor.BlockEdit',
- 'core/editor/position/with-inspector-controls',
- withPositionControls
-);
diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js
index 1acb2cda3ac01..4036342316887 100644
--- a/packages/block-editor/src/hooks/style.js
+++ b/packages/block-editor/src/hooks/style.js
@@ -32,7 +32,6 @@ import {
SPACING_SUPPORT_KEY,
DimensionsPanel,
} from './dimensions';
-import useDisplayBlockControls from '../components/use-display-block-controls';
import {
shouldSkipSerialization,
useStyleOverride,
@@ -356,12 +355,16 @@ function BlockStyleControls( {
__unstableParentLayout,
} ) {
const settings = useBlockSettings( name, __unstableParentLayout );
+ const blockEditingMode = useBlockEditingMode();
const passedProps = {
clientId,
name,
setAttributes,
settings,
};
+ if ( blockEditingMode !== 'default' ) {
+ return null;
+ }
return (
<>
@@ -373,34 +376,10 @@ function BlockStyleControls( {
);
}
-/**
- * Override the default edit UI to include new inspector controls for
- * all the custom styles configs.
- *
- * @param {Function} BlockEdit Original component.
- *
- * @return {Function} Wrapped component.
- */
-export const withBlockStyleControls = createHigherOrderComponent(
- ( BlockEdit ) => ( props ) => {
- if ( ! hasStyleSupport( props.name ) ) {
- return ;
- }
-
- const shouldDisplayControls = useDisplayBlockControls();
- const blockEditingMode = useBlockEditingMode();
-
- return (
- <>
- { shouldDisplayControls && blockEditingMode === 'default' && (
-
- ) }
-
- >
- );
- },
- 'withBlockStyleControls'
-);
+export default {
+ edit: BlockStyleControls,
+ hasSupport: hasStyleSupport,
+};
// Defines which element types are supported, including their hover styles or
// any other elements that have been included under a single element type
@@ -542,12 +521,6 @@ addFilter(
addEditProps
);
-addFilter(
- 'editor.BlockEdit',
- 'core/style/with-block-controls',
- withBlockStyleControls
-);
-
addFilter(
'editor.BlockListBlock',
'core/editor/with-elements-styles',
diff --git a/packages/block-editor/src/hooks/test/align.js b/packages/block-editor/src/hooks/test/align.js
index b928e6eafc8b2..c695399e993b0 100644
--- a/packages/block-editor/src/hooks/test/align.js
+++ b/packages/block-editor/src/hooks/test/align.js
@@ -12,20 +12,12 @@ import {
registerBlockType,
unregisterBlockType,
} from '@wordpress/blocks';
-import { SlotFillProvider } from '@wordpress/components';
/**
* Internal dependencies
*/
-import BlockControls from '../../components/block-controls';
-import BlockEdit from '../../components/block-edit';
import BlockEditorProvider from '../../components/provider';
-import {
- getValidAlignments,
- withAlignmentControls,
- withDataAlign,
- addAssignedAlign,
-} from '../align';
+import { getValidAlignments, withDataAlign, addAssignedAlign } from '../align';
const noop = () => {};
@@ -157,68 +149,6 @@ describe( 'align', () => {
} );
} );
- describe( 'withAlignControls', () => {
- const componentProps = {
- name: 'core/foo',
- attributes: {},
- isSelected: true,
- };
-
- it( 'should do nothing if no valid alignments', () => {
- registerBlockType( 'core/foo', blockSettings );
-
- const EnhancedComponent = withAlignmentControls(
- ( { wrapperProps } ) =>
- );
-
- render(
-
-
-
-
-
-
- );
-
- expect(
- screen.queryByRole( 'button', {
- name: 'Align',
- expanded: false,
- } )
- ).not.toBeInTheDocument();
- } );
-
- it( 'should render toolbar controls if valid alignments', () => {
- registerBlockType( 'core/foo', {
- ...blockSettings,
- supports: {
- align: true,
- alignWide: false,
- },
- } );
-
- const EnhancedComponent = withAlignmentControls(
- ( { wrapperProps } ) =>
- );
-
- render(
-
-
-
-
-
-
- );
-
- expect(
- screen.getAllByRole( 'button', {
- name: 'Align',
- expanded: false,
- } )
- ).toHaveLength( 2 );
- } );
- } );
-
describe( 'withDataAlign', () => {
it( 'should render with wrapper props', () => {
registerBlockType( 'core/foo', {
diff --git a/packages/block-editor/src/hooks/utils.js b/packages/block-editor/src/hooks/utils.js
index 5985b821d00a8..98638ae5dabf5 100644
--- a/packages/block-editor/src/hooks/utils.js
+++ b/packages/block-editor/src/hooks/utils.js
@@ -4,10 +4,13 @@
import { getBlockSupport } from '@wordpress/blocks';
import { useMemo, useEffect, useId } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
+import { createHigherOrderComponent, pure } from '@wordpress/compose';
+import { addFilter } from '@wordpress/hooks';
/**
* Internal dependencies
*/
+import useDisplayBlockControls from '../components/use-display-block-controls';
import { useSettings } from '../components';
import { useSettingsForBlockElement } from '../components/global-styles/hooks';
import { getValueFromObjectPath, setImmutably } from '../utils/object';
@@ -362,3 +365,68 @@ export function useBlockSettings( name, parentLayout ) {
return useSettingsForBlockElement( rawSettings, name );
}
+
+export function createBlockEditFilter( features ) {
+ // We don't want block controls to re-render when typing inside a block.
+ // `pure` will prevent re-renders unless props change, so only pass the
+ // needed props and not the whole attributes object.
+ features = features.map( ( settings ) => {
+ return { ...settings, Edit: pure( settings.edit ) };
+ } );
+ const withBlockEditHooks = createHigherOrderComponent(
+ ( OriginalBlockEdit ) => ( props ) => {
+ const { isDisplayed, isParentDisplayed } =
+ useDisplayBlockControls();
+ // CAUTION: code added before this line will be executed for all
+ // blocks, not just those that support the feature! Code added
+ // above this line should be carefully evaluated for its impact on
+ // performance.
+ return [
+ ...features.map( ( feature, i ) => {
+ const {
+ Edit,
+ hasSupport,
+ attributeKeys = [],
+ shareWithChildBlocks,
+ } = feature;
+ const shouldDisplayControls =
+ isDisplayed ||
+ ( isParentDisplayed && shareWithChildBlocks );
+
+ if (
+ ! shouldDisplayControls ||
+ ! hasSupport( props.name )
+ ) {
+ return null;
+ }
+
+ const neededProps = {};
+ for ( const key of attributeKeys ) {
+ if ( props.attributes[ key ] ) {
+ neededProps[ key ] = props.attributes[ key ];
+ }
+ }
+ return (
+
+ );
+ } ),
+ ,
+ ];
+ },
+ 'withBlockEditHooks'
+ );
+ addFilter( 'editor.BlockEdit', 'core/editor/hooks', withBlockEditHooks );
+}