Skip to content

Commit

Permalink
Block Editor: Check for multiple block usage in the block-editor pack…
Browse files Browse the repository at this point in the history
…age (#62086)

Co-authored-by: youknowriad <[email protected]>
Co-authored-by: ellatrix <[email protected]>
  • Loading branch information
3 people authored May 29, 2024
1 parent e8bec8d commit a12fa90
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 170 deletions.
15 changes: 13 additions & 2 deletions packages/block-editor/src/components/block-edit/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
* WordPress dependencies
*/
import { useMemo } from '@wordpress/element';

import { useMemo, useContext } from '@wordpress/element';
import { hasBlockSupport } from '@wordpress/blocks';

/**
* Internal dependencies
*/
Expand All @@ -17,6 +17,8 @@ import {
blockBindingsKey,
isPreviewModeKey,
} from './context';
import { MultipleUsageWarning } from './multiple-usage-warning';
import { PrivateBlockContext } from '../block-list/private-block-context';

/**
* The `useBlockEditContext` hook provides information about the block this hook is being used in.
Expand Down Expand Up @@ -49,6 +51,8 @@ export default function BlockEdit( {
const layoutSupport =
hasBlockSupport( name, 'layout', false ) ||
hasBlockSupport( name, '__experimentalLayout', false );
const { originalBlockClientId } = useContext( PrivateBlockContext );

return (
<BlockEditContextProvider
// It is important to return the same object if props haven't
Expand Down Expand Up @@ -85,6 +89,13 @@ export default function BlockEdit( {
) }
>
<Edit { ...props } />
{ originalBlockClientId && (
<MultipleUsageWarning
originalBlockClientId={ originalBlockClientId }
name={ name }
onReplace={ props.onReplace }
/>
) }
</BlockEditContextProvider>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* WordPress dependencies
*/
import { getBlockType } from '@wordpress/blocks';
import { Button } from '@wordpress/components';
import { useDispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../../store';
import Warning from '../warning';

export function MultipleUsageWarning( {
originalBlockClientId,
name,
onReplace,
} ) {
const { selectBlock } = useDispatch( blockEditorStore );
const blockType = getBlockType( name );

return (
<Warning
actions={ [
<Button
key="find-original"
variant="secondary"
onClick={ () => selectBlock( originalBlockClientId ) }
>
{ __( 'Find original' ) }
</Button>,
<Button
key="remove"
variant="secondary"
onClick={ () => onReplace( [] ) }
>
{ __( 'Remove' ) }
</Button>,
] }
>
<strong>{ blockType?.title }: </strong>
{ __( 'This block can only be used once.' ) }
</Warning>
);
}
18 changes: 18 additions & 0 deletions packages/block-editor/src/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
isUnmodifiedBlock,
isReusableBlock,
getBlockDefaultClassName,
hasBlockSupport,
store as blocksStore,
} from '@wordpress/blocks';
import { withFilters } from '@wordpress/components';
Expand Down Expand Up @@ -534,6 +535,7 @@ function BlockListBlockProvider( props ) {
isFirstMultiSelectedBlock,
getMultiSelectedBlockClientIds,
hasSelectedInnerBlock,
getBlocksByName,

getBlockIndex,
isBlockMultiSelected,
Expand Down Expand Up @@ -607,6 +609,17 @@ function BlockListBlockProvider( props ) {
const movingClientId = hasBlockMovingClientId();
const blockEditingMode = getBlockEditingMode( clientId );

const multiple = hasBlockSupport( blockName, 'multiple', true );

// For block types with `multiple` support, there is no "original
// block" to be found in the content, as the block itself is valid.
const blocksWithSameName = multiple
? []
: getBlocksByName( blockName );
const isInvalid =
blocksWithSameName.length &&
blocksWithSameName[ 0 ] !== clientId;

return {
...previewContext,
mode: getBlockMode( clientId ),
Expand Down Expand Up @@ -664,6 +677,9 @@ function BlockListBlockProvider( props ) {
hasEditableOutline:
blockEditingMode !== 'disabled' &&
getBlockEditingMode( rootClientId ) === 'disabled',
originalBlockClientId: isInvalid
? blocksWithSameName[ 0 ]
: false,
};
},
[ clientId, rootClientId ]
Expand Down Expand Up @@ -707,6 +723,7 @@ function BlockListBlockProvider( props ) {
hasEditableOutline,
className,
defaultClassName,
originalBlockClientId,
} = selectedProps;

// Users of the editor.BlockListBlock filter used to be able to
Expand Down Expand Up @@ -754,6 +771,7 @@ function BlockListBlockProvider( props ) {
defaultClassName,
mayDisplayControls,
mayDisplayParentControls,
originalBlockClientId,
themeSupportsLayout,
};

Expand Down
4 changes: 0 additions & 4 deletions packages/edit-post/src/hooks/index.js

This file was deleted.

163 changes: 0 additions & 163 deletions packages/edit-post/src/hooks/validate-multiple-use/index.js

This file was deleted.

1 change: 0 additions & 1 deletion packages/edit-post/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { store as editorStore } from '@wordpress/editor';
/**
* Internal dependencies
*/
import './hooks';
import Editor from './editor';

/**
Expand Down

0 comments on commit a12fa90

Please sign in to comment.