+
+ {} } />
+
+
+
+
+ { blockTitle }
+
+
+
+
+
+
+
);
}
diff --git a/packages/block-editor/src/components/list-view/index.js b/packages/block-editor/src/components/list-view/index.js
index 315a6153839d1..5270a7af3a296 100644
--- a/packages/block-editor/src/components/list-view/index.js
+++ b/packages/block-editor/src/components/list-view/index.js
@@ -1,3 +1,8 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+
/**
* WordPress dependencies
*/
@@ -28,8 +33,9 @@ import { __ } from '@wordpress/i18n';
*/
import ListViewBranch from './branch';
import { ListViewContext } from './context';
-import ListViewDropIndicator from './drop-indicator';
+import ListViewDropIndicatorPreview from './drop-indicator';
import useBlockSelection from './use-block-selection';
+import useListViewBlockIndexes from './use-list-view-block-indexes';
import useListViewClientIds from './use-list-view-client-ids';
import useListViewDropZone from './use-list-view-drop-zone';
import useListViewExpandSelectedItem from './use-list-view-expand-selected-item';
@@ -105,6 +111,7 @@ function ListViewComponent(
const instanceId = useInstanceId( ListViewComponent );
const { clientIdsTree, draggedClientIds, selectedClientIds } =
useListViewClientIds( { blocks, rootClientId } );
+ const blockIndexes = useListViewBlockIndexes( clientIdsTree );
const { getBlock } = useSelect( blockEditorStore );
const { visibleBlockCount, shouldShowInnerBlocks } = useSelect(
@@ -132,6 +139,8 @@ function ListViewComponent(
const { ref: dropZoneRef, target: blockDropTarget } = useListViewDropZone( {
dropZoneElement,
+ expandedState,
+ setExpandedState,
} );
const elementRef = useRef();
const treeGridRef = useMergeRefs( [ elementRef, dropZoneRef, ref ] );
@@ -210,11 +219,55 @@ function ListViewComponent(
[ updateBlockSelection ]
);
+ const firstDraggedBlockClientId = draggedClientIds?.[ 0 ];
+
+ // Convert a blockDropTarget into indexes relative to the blocks in the list view.
+ // These values are used to determine which blocks should be displaced to make room
+ // for the drop indicator. See `ListViewBranch` and `getDragDisplacementValues`.
+ const { blockDropTargetIndex, blockDropPosition, firstDraggedBlockIndex } =
+ useMemo( () => {
+ let _blockDropTargetIndex, _firstDraggedBlockIndex;
+
+ if ( blockDropTarget?.clientId ) {
+ const foundBlockIndex =
+ blockIndexes[ blockDropTarget.clientId ];
+ // If dragging below or inside the block, treat the drop target as the next block.
+ _blockDropTargetIndex =
+ foundBlockIndex === undefined ||
+ blockDropTarget?.dropPosition === 'top'
+ ? foundBlockIndex
+ : foundBlockIndex + 1;
+ } else if ( blockDropTarget === null ) {
+ // A `null` value is used to indicate that the user is dragging outside of the list view.
+ _blockDropTargetIndex = null;
+ }
+
+ if ( firstDraggedBlockClientId ) {
+ const foundBlockIndex =
+ blockIndexes[ firstDraggedBlockClientId ];
+ _firstDraggedBlockIndex =
+ foundBlockIndex === undefined ||
+ blockDropTarget?.dropPosition === 'top'
+ ? foundBlockIndex
+ : foundBlockIndex + 1;
+ }
+
+ return {
+ blockDropTargetIndex: _blockDropTargetIndex,
+ blockDropPosition: blockDropTarget?.dropPosition,
+ firstDraggedBlockIndex: _firstDraggedBlockIndex,
+ };
+ }, [ blockDropTarget, blockIndexes, firstDraggedBlockClientId ] );
+
const contextValue = useMemo(
() => ( {
+ blockDropPosition,
+ blockDropTargetIndex,
+ blockIndexes,
draggedClientIds,
expandedState,
expand,
+ firstDraggedBlockIndex,
collapse,
BlockSettingsMenu,
listViewInstanceId: instanceId,
@@ -225,9 +278,13 @@ function ListViewComponent(
rootClientId,
} ),
[
+ blockDropPosition,
+ blockDropTargetIndex,
+ blockIndexes,
draggedClientIds,
expandedState,
expand,
+ firstDraggedBlockIndex,
collapse,
BlockSettingsMenu,
instanceId,
@@ -267,7 +324,8 @@ function ListViewComponent(
return (