Skip to content

Commit

Permalink
Drop to either side of target block
Browse files Browse the repository at this point in the history
  • Loading branch information
tellthemachines committed Dec 1, 2023
1 parent 889d7f8 commit 9a90c2d
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 19 deletions.
24 changes: 17 additions & 7 deletions packages/block-editor/src/components/block-popover/inbetween.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function BlockPopoverInbetween( {
__unstablePopoverSlot,
__unstableContentRef,
operation = 'insert',
nearestSide = 'right',
...props
} ) {
// This is a temporary hack to get the inbetween inserter to recompute properly.
Expand Down Expand Up @@ -82,7 +83,10 @@ function BlockPopoverInbetween( {
return undefined;
}

const contextElement = previousElement || nextElement;
const contextElement =
operation === 'group'
? nextElement || previousElement
: previousElement || nextElement;

return {
contextElement,
Expand All @@ -100,12 +104,16 @@ function BlockPopoverInbetween( {
let height = 0;

if ( operation === 'group' ) {
// If the operation is group, nextRect is the target to be grouped.
// Not sure if previousRect is needed here.
top = nextRect ? nextRect.top : previousRect.top;
width = nextRect ? nextRect.width : previousRect.width;
height = nextRect ? nextRect.bottom - nextRect.top : 0;
left = nextRect ? nextRect.left : previousRect.left;
const targetRect = nextRect || previousRect;
top = targetRect.top;
width = targetRect.width;
height = targetRect.bottom - targetRect.top;
// Popover calculates its distance from mid-block so some
// adjustments are needed to make it appear in the right place.
left =
nearestSide === 'left'
? -targetRect.width / 2 + targetRect.left
: targetRect.width / 2 + targetRect.left;
} else if ( isVertical ) {
// vertical
top = previousRect ? previousRect.bottom : nextRect.top;
Expand Down Expand Up @@ -149,6 +157,8 @@ function BlockPopoverInbetween( {
popoverRecomputeCounter,
isVertical,
isVisible,
operation,
nearestSide,
] );

const popoverScrollRef = usePopoverScroll( __unstableContentRef );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function InbetweenInsertionPointPopover( {
__unstablePopoverSlot,
__unstableContentRef,
operation = 'insert',
nearestSide = 'right',
} ) {
const { selectBlock, hideInsertionPoint } = useDispatch( blockEditorStore );
const openRef = useContext( InsertionPointOpenRef );
Expand Down Expand Up @@ -156,6 +157,7 @@ function InbetweenInsertionPointPopover( {
__unstablePopoverSlot={ __unstablePopoverSlot }
__unstableContentRef={ __unstableContentRef }
operation={ operation }
nearestSide={ nearestSide }
>
<motion.div
layout={ ! disableMotion }
Expand Down Expand Up @@ -245,6 +247,7 @@ export default function InsertionPoint( props ) {
) : (
<InbetweenInsertionPointPopover
operation={ insertionPoint.operation }
nearestSide={ insertionPoint.nearestSide }
{ ...props }
/>
);
Expand Down
24 changes: 18 additions & 6 deletions packages/block-editor/src/components/use-block-drop-zone/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export function getDropTargetPosition(
let insertPosition = 'before';
let minDistance = Infinity;
let targetBlockIndex = null;
let nearestSide = 'right';

blocksData.forEach(
( { isUnmodifiedDefaultBlock, getBoundingClientRect, blockIndex } ) => {
Expand All @@ -86,6 +87,13 @@ export function getDropTargetPosition(
// Set target block index if the point is inside of the block
// and the block is modified.
targetBlockIndex = blockIndex;
// If the point is inside of the block, find nearest side.
const [ , sideEdge ] = getDistanceToNearestEdge(
position,
rect,
[ 'left', 'right' ]
);
nearestSide = sideEdge;
}

if ( distance < minDistance ) {
Expand Down Expand Up @@ -113,7 +121,7 @@ export function getDropTargetPosition(

// If the target index is set then group with the block at that index.
if ( targetBlockIndex !== null ) {
return [ targetBlockIndex, 'group' ];
return [ targetBlockIndex, 'group', nearestSide ];
}
// If both blocks are not unmodified default blocks then just insert between them.
if (
Expand Down Expand Up @@ -181,6 +189,7 @@ export default function useBlockDropZone( {

const onBlockDrop = useOnBlockDrop( targetRootClientId, dropTarget.index, {
operation: dropTarget.operation,
nearestSide: dropTarget.nearestSide,
} );
const throttled = useThrottle(
useCallback(
Expand Down Expand Up @@ -215,19 +224,22 @@ export default function useBlockDropZone( {
};
} );

const [ targetIndex, operation ] = getDropTargetPosition(
blocksData,
{ x: event.clientX, y: event.clientY },
getBlockListSettings( targetRootClientId )?.orientation
);
const [ targetIndex, operation, nearestSide ] =
getDropTargetPosition(
blocksData,
{ x: event.clientX, y: event.clientY },
getBlockListSettings( targetRootClientId )?.orientation
);

registry.batch( () => {
setDropTarget( {
index: targetIndex,
operation,
nearestSide,
} );
showInsertionPoint( targetRootClientId, targetIndex, {
operation,
nearestSide,
} );
} );
},
Expand Down
10 changes: 7 additions & 3 deletions packages/block-editor/src/components/use-on-block-drop/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ export default function useOnBlockDrop(
targetBlockIndex,
options = {}
) {
const { operation = 'insert' } = options;
const { operation = 'insert', nearestSide = 'right' } = options;
const hasUploadPermissions = useSelect(
( select ) => select( blockEditorStore ).getSettings().mediaUpload,
[]
Expand Down Expand Up @@ -266,7 +266,11 @@ export default function useOnBlockDrop(
replaceBlocks( clientId, blocks, undefined, initialPosition );
} else if ( operation === 'group' ) {
const targetBlock = getBlock( clientId );
blocks.unshift( targetBlock );
if ( nearestSide === 'left' ) {
blocks.push( targetBlock );
} else {
blocks.unshift( targetBlock );
}

const groupInnerBlocks = blocks.map( ( block ) => {
return createBlock(
Expand All @@ -279,7 +283,7 @@ export default function useOnBlockDrop(
const wrappedBlocks = createBlock(
'core/group',
{
layout: { type: 'flex' },
layout: { type: 'flex', flexWrap: 'nowrap' },
},
groupInnerBlocks
);
Expand Down
4 changes: 3 additions & 1 deletion packages/block-editor/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -640,13 +640,15 @@ export function showInsertionPoint(
index,
__unstableOptions = {}
) {
const { __unstableWithInserter, operation } = __unstableOptions;
const { __unstableWithInserter, operation, nearestSide } =
__unstableOptions;
return {
type: 'SHOW_INSERTION_POINT',
rootClientId,
index,
__unstableWithInserter,
operation,
nearestSide,
};
}
/**
Expand Down
10 changes: 8 additions & 2 deletions packages/block-editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1580,13 +1580,19 @@ export function blocksMode( state = {}, action ) {
export function insertionPoint( state = null, action ) {
switch ( action.type ) {
case 'SHOW_INSERTION_POINT': {
const { rootClientId, index, __unstableWithInserter, operation } =
action;
const {
rootClientId,
index,
__unstableWithInserter,
operation,
nearestSide,
} = action;
const nextState = {
rootClientId,
index,
__unstableWithInserter,
operation,
nearestSide,
};

// Bail out updates if the states are the same.
Expand Down

0 comments on commit 9a90c2d

Please sign in to comment.