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

List View: Try allowing users to drag to one level up the hierarchy #49498

Closed
wants to merge 2 commits into from
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ function isNestingGesture( point, rect ) {
return point.x > blockCenterX;
}

/**
* Determines whether the user is positioning the dragged block so as to move
* up one level in the block hierarchy.
*
* Presently this is determined by whether the cursor is within the left 1/4 side
* of the block.
*
* @param {WPPoint} point The point representing the cursor position when dragging.
* @param {DOMRect} rect The rectangle.
*/
function isUpGesture( point, rect ) {
const blockQuarterX = rect.left + rect.width / 4;
return point.x < blockQuarterX;
}

// Block navigation is always a vertical list, so only allow dropping
// to the above or below a block.
const ALLOWED_DROP_EDGES = [ 'top', 'bottom' ];
Expand Down Expand Up @@ -145,6 +160,27 @@ export function getListViewDropTarget( blocksData, position ) {

const isDraggingBelow = candidateEdge === 'bottom';

// If the user is dragging towards the bottom of the block check whether
// they might be trying to move the block up one level.
// For this to be true, the block must be the last child of its parent,
// and the block must be able to be inserted as a sibling of the block's parent.
if (
isDraggingBelow &&
candidateBlockData.isLastChildOfRoot &&
candidateBlockData.canInsertDraggedBlocksIntoParent &&
candidateBlockData.rootClientId &&
isUpGesture( position, candidateRect )
) {
return {
rootClientId:
candidateBlockData.parentOfRootClientId ??
candidateBlockData.rootClientId,
clientId: candidateBlockData.clientId, // This is used as the target for the drop indicator.
blockIndex: candidateBlockData.parentBlockIndex + 1,
dropPosition: candidateEdge,
};
}

// If the user is dragging towards the bottom of the block check whether
// they might be trying to nest the block as a child.
// If the block already has inner blocks, and is expanded, this should be treated
Expand Down Expand Up @@ -190,6 +226,7 @@ export default function useListViewDropZone() {
getBlockRootClientId,
getBlockIndex,
getBlockCount,
getBlocks,
getDraggedBlockClientIds,
canInsertBlocks,
} = useSelect( blockEditorStore );
Expand All @@ -214,12 +251,25 @@ export default function useListViewDropZone() {
const clientId = blockElement.dataset.block;
const isExpanded = blockElement.dataset.expanded === 'true';
const rootClientId = getBlockRootClientId( clientId );
const parentOfRootClientId =
getBlockRootClientId( rootClientId );
const childrenOfRootClientId = getBlocks( rootClientId );
const isLastChildOfRoot =
childrenOfRootClientId.length > 0 &&
childrenOfRootClientId[
childrenOfRootClientId.length - 1
]?.clientId === clientId;
const blockIndex = getBlockIndex( clientId );

return {
clientId,
isExpanded,
isLastChildOfRoot,
parentOfRootClientId,
rootClientId,
blockIndex: getBlockIndex( clientId ),
blockIndex,
parentBlockIndex:
getBlockIndex( rootClientId ) || blockIndex,
element: blockElement,
isDraggedBlock: isBlockDrag
? draggedBlockClientIds.includes( clientId )
Expand All @@ -231,6 +281,13 @@ export default function useListViewDropZone() {
rootClientId
)
: true,
canInsertDraggedBlocksIntoParent:
isBlockDrag && parentOfRootClientId
? canInsertBlocks(
draggedBlockClientIds,
parentOfRootClientId
)
: true,
canInsertDraggedBlocksAsChild: isBlockDrag
? canInsertBlocks( draggedBlockClientIds, clientId )
: true,
Expand Down