Skip to content

Commit d93011b

Browse files
committed
Try allowing blocks to be nested when dragging below, first attempt
1 parent 09be7e0 commit d93011b

File tree

6 files changed

+88
-14
lines changed

6 files changed

+88
-14
lines changed

docs/designers-developers/developers/data/data-core-block-editor.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,18 @@ _Returns_
363363

364364
- `Array`: ids of top-level and descendant blocks.
365365

366+
<a name="getDraggedBlockClientIds" href="#getDraggedBlockClientIds">#</a> **getDraggedBlockClientIds**
367+
368+
Returns the dragged block client ids.
369+
370+
_Parameters_
371+
372+
- _state_ `Object`: Global application state.
373+
374+
_Returns_
375+
376+
- `boolean`: Whether user is dragging blocks.
377+
366378
<a name="getFirstMultiSelectedBlockClientId" href="#getFirstMultiSelectedBlockClientId">#</a> **getFirstMultiSelectedBlockClientId**
367379

368380
Returns the client ID of the first block in the multi-selection set, or null
@@ -1341,6 +1353,10 @@ _Returns_
13411353

13421354
Returns an action object used in signalling that the user has begun to drag blocks.
13431355

1356+
_Parameters_
1357+
1358+
- _clientIds_ `Array<string>`: An array of client ids being dragged
1359+
13441360
_Returns_
13451361

13461362
- `Object`: Action object.

packages/block-editor/src/components/block-draggable/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ const BlockDraggable = ( {
7272
elementId={ elementId || `block-${ clientIds[ 0 ] }` }
7373
transferData={ transferData }
7474
onDragStart={ ( event ) => {
75-
startDraggingBlocks();
75+
startDraggingBlocks( clientIds );
7676
isDragging.current = true;
7777

7878
startScrolling( event );

packages/block-editor/src/components/block-navigation/use-block-navigation-drop-zone.js

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,24 @@ import useOnHTMLDrop from '../use-block-drop-zone/use-on-html-drop';
1313
import useOnFileDrop from '../use-block-drop-zone/use-on-file-drop';
1414
import useOnBlockDrop from '../use-block-drop-zone/use-on-block-drop';
1515

16-
function getDropTargetBlocksData( ref, getRootClientId, getBlockIndex ) {
16+
function getDropTargetBlocksData(
17+
ref,
18+
dragEventType,
19+
getRootClientId,
20+
getBlockIndex,
21+
getDraggedBlockClientIds,
22+
canInsertBlocks
23+
) {
1724
if ( ! ref.current ) {
1825
return;
1926
}
2027

28+
const isBlockDrag = dragEventType === 'default';
29+
30+
const draggedBlockClientIds = isBlockDrag
31+
? getDraggedBlockClientIds()
32+
: undefined;
33+
2134
const blockElements = Array.from(
2235
ref.current.querySelectorAll( '[data-block]' )
2336
);
@@ -32,6 +45,12 @@ function getDropTargetBlocksData( ref, getRootClientId, getBlockIndex ) {
3245
blockIndex: getBlockIndex( clientId, rootClientId ),
3346
element: blockElement,
3447
orientation: 'vertical',
48+
canInsertDraggedBlocksAsSibling: isBlockDrag
49+
? canInsertBlocks( draggedBlockClientIds, rootClientId )
50+
: true,
51+
canInsertDraggedBlocksAsChild: isBlockDrag
52+
? canInsertBlocks( draggedBlockClientIds, clientId )
53+
: true,
3554
};
3655
} );
3756
}
@@ -41,7 +60,7 @@ function getDropTargetBlocksData( ref, getRootClientId, getBlockIndex ) {
4160
const ALLOWED_DROP_EDGES = [ 'top', 'bottom' ];
4261

4362
function getBlockNavigationDropTarget( blocksData, position ) {
44-
let offset;
63+
let candidateEdge;
4564
let candidateBlockData;
4665
let candidateDistance;
4766

@@ -56,29 +75,51 @@ function getBlockNavigationDropTarget( blocksData, position ) {
5675
if ( candidateDistance === undefined || distance < candidateDistance ) {
5776
candidateDistance = distance;
5877
candidateBlockData = blockData;
59-
offset = edge === 'bottom' ? 1 : 0;
78+
candidateEdge = edge;
6079
}
6180
} );
6281

6382
if ( ! candidateBlockData ) {
6483
return;
6584
}
6685

86+
const isDraggingBelow = candidateEdge === 'bottom';
87+
88+
// If the user is dragging towards the bottom of the block interpret that
89+
// they're trying to next the dragged block.
90+
if ( isDraggingBelow && candidateBlockData.canInsertDraggedBlocksAsChild ) {
91+
return {
92+
rootClientId: candidateBlockData.clientId,
93+
blockIndex: 0,
94+
};
95+
}
96+
97+
const offset = isDraggingBelow ? 1 : 0;
98+
6799
return {
68100
rootClientId: candidateBlockData.rootClientId,
69101
blockIndex: candidateBlockData.blockIndex + offset,
70102
};
71103
}
72104

73105
export default function useBlockNavigationDropZone( ref ) {
74-
const { getBlockRootClientId, getBlockIndex } = useSelect( ( select ) => {
106+
const {
107+
canInsertBlocks,
108+
getBlockRootClientId,
109+
getBlockIndex,
110+
getDraggedBlockClientIds,
111+
} = useSelect( ( select ) => {
75112
const {
113+
canInsertBlocks: _canInsertBlocks,
76114
getBlockRootClientId: _getBlockRootClientId,
77115
getBlockIndex: _getBlockIndex,
116+
getDraggedBlockClientIds: _getDraggedBlockClientIds,
78117
} = select( 'core/block-editor' );
79118
return {
119+
canInsertBlocks: _canInsertBlocks,
80120
getBlockRootClientId: _getBlockRootClientId,
81121
getBlockIndex: _getBlockIndex,
122+
getDraggedBlockClientIds: _getDraggedBlockClientIds,
82123
};
83124
}, [] );
84125

@@ -92,7 +133,7 @@ export default function useBlockNavigationDropZone( ref ) {
92133
const onFilesDrop = useOnFileDrop( targetRootClientId, targetBlockIndex );
93134
const onDrop = useOnBlockDrop( targetRootClientId, targetBlockIndex );
94135

95-
const { position } = useDropZone( {
136+
const { position, type: dragEventType } = useDropZone( {
96137
element: ref,
97138
onFilesDrop,
98139
onHTMLDrop,
@@ -108,8 +149,11 @@ export default function useBlockNavigationDropZone( ref ) {
108149
if ( hasPosition ) {
109150
blocksData.current = getDropTargetBlocksData(
110151
ref,
152+
dragEventType,
111153
getBlockRootClientId,
112-
getBlockIndex
154+
getBlockIndex,
155+
getDraggedBlockClientIds,
156+
canInsertBlocks
113157
);
114158
}
115159
}, [ hasPosition ] );

packages/block-editor/src/store/actions.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,11 +718,14 @@ export function stopTyping() {
718718
/**
719719
* Returns an action object used in signalling that the user has begun to drag blocks.
720720
*
721+
* @param {string[]} clientIds An array of client ids being dragged
722+
*
721723
* @return {Object} Action object.
722724
*/
723-
export function startDraggingBlocks() {
725+
export function startDraggingBlocks( clientIds ) {
724726
return {
725727
type: 'START_DRAGGING_BLOCKS',
728+
clientIds,
726729
};
727730
}
728731

packages/block-editor/src/store/reducer.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,20 +1131,20 @@ export function isTyping( state = false, action ) {
11311131
}
11321132

11331133
/**
1134-
* Reducer returning dragging state.
1134+
* Reducer returning dragged block client id.
11351135
*
11361136
* @param {boolean} state Current state.
11371137
* @param {Object} action Dispatched action.
11381138
*
11391139
* @return {boolean} Updated state.
11401140
*/
1141-
export function isDraggingBlocks( state = false, action ) {
1141+
export function draggedBlocks( state = null, action ) {
11421142
switch ( action.type ) {
11431143
case 'START_DRAGGING_BLOCKS':
1144-
return true;
1144+
return action.clientIds;
11451145

11461146
case 'STOP_DRAGGING_BLOCKS':
1147-
return false;
1147+
return null;
11481148
}
11491149

11501150
return state;
@@ -1646,7 +1646,7 @@ export function highlightedBlock( state, action ) {
16461646
export default combineReducers( {
16471647
blocks,
16481648
isTyping,
1649-
isDraggingBlocks,
1649+
draggedBlocks,
16501650
isCaretWithinFormattedText,
16511651
selectionStart,
16521652
selectionEnd,

packages/block-editor/src/store/selectors.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,18 @@ export function isTyping( state ) {
10061006
* @return {boolean} Whether user is dragging blocks.
10071007
*/
10081008
export function isDraggingBlocks( state ) {
1009-
return state.isDraggingBlocks;
1009+
return !! state.draggedBlocks;
1010+
}
1011+
1012+
/**
1013+
* Returns the dragged block client ids.
1014+
*
1015+
* @param {Object} state Global application state.
1016+
*
1017+
* @return {boolean} Whether user is dragging blocks.
1018+
*/
1019+
export function getDraggedBlockClientIds( state ) {
1020+
return state.draggedBlocks;
10101021
}
10111022

10121023
/**

0 commit comments

Comments
 (0)