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

Add drag and drop to List View in Navigation Screen #23952

Merged
merged 45 commits into from
Sep 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
8a21e07
Split useBlockDropZone into multiple hooks
talldan Jul 9, 2020
38d35f3
Add Draggable to block navigation block component
talldan Jul 9, 2020
a04561a
Add block navigation drop zone hook
talldan Jul 10, 2020
a99b86b
Allow tree grid component to take a ref
talldan Jul 10, 2020
c3aadf6
Add drop zone to block navigation tree
talldan Jul 10, 2020
4004f3a
Allow custom elementId in BlockDraggable component
talldan Jul 10, 2020
73f720c
Move block draggable to block contents and add simple initial drop in…
talldan Jul 14, 2020
46b3781
Fix block drop index
talldan Jul 15, 2020
4c60abe
Try allowing blocks to be nested when dragging below, first attempt
talldan Jul 16, 2020
7ec4e6e
Break early when cursor is contained by block
talldan Aug 7, 2020
50cef87
Improve drop zone detection
talldan Aug 7, 2020
9f4a58e
Fix issue where incorrect drop position selected when blocks overlap
talldan Aug 7, 2020
b7bb995
Improve drop zone indicators
talldan Aug 7, 2020
002f2af
Hide dragged block in list view
talldan Aug 11, 2020
b686591
Refactor selector
talldan Aug 11, 2020
2b31ec7
Hide dragged block children in list view
talldan Aug 11, 2020
c188c8d
Hide appender when dragging parent
talldan Aug 11, 2020
30413e3
Fix block draggable chip error
talldan Aug 11, 2020
45947ba
Refactor block drop event handlers into a single hook
talldan Aug 19, 2020
98f438f
Disallow dropping in invalid block context
talldan Aug 19, 2020
d6b1d3f
Allow nesting from both above and below the insertion point
talldan Aug 19, 2020
2d7f589
remove unused data
talldan Aug 19, 2020
0c6dbfe
Fix comment
talldan Aug 19, 2020
7db0623
Try a separate fixed position element for the drop indicator
talldan Aug 20, 2020
753008a
Update styles to improve drop zone indicator
talldan Aug 20, 2020
43fcff6
Fix media dragging and dropping
talldan Aug 20, 2020
6c483ef
Fix incorrect import
talldan Aug 27, 2020
f550d91
Fix dropping blocks with no drop indicators
talldan Aug 27, 2020
26160e6
Tidy up nesting code
talldan Aug 27, 2020
abf316d
Fix useRef/useEffect anti-pattern, replace with useMemo
talldan Aug 27, 2020
f24cc0b
Wrap up selectors in an object
talldan Aug 27, 2020
9c715da
Convert getDropTargetBlocksData into a hook so that selectors can be …
talldan Aug 27, 2020
7ad776d
Add doc blocks
talldan Aug 27, 2020
f77e540
Revert "Update styles to improve drop zone indicator"
talldan Aug 27, 2020
3d72f3f
Avoid showing drop zone on dragged block
talldan Aug 27, 2020
9d77457
Improve styles
talldan Aug 27, 2020
2bc3dbb
Try making the list view popover a modal drop zone
talldan Aug 27, 2020
19c1120
Adjust drop indicator styles
talldan Aug 27, 2020
28f3131
Use __experimentalFeatures to disable drag and drop outside of naviga…
talldan Aug 28, 2020
538b112
Revert "Try making the list view popover a modal drop zone"
talldan Aug 28, 2020
9d9e228
Make selectors more succinct
talldan Aug 28, 2020
575aa75
Change useMemo back to useEffect to ensure blocksData is recomputed c…
talldan Aug 28, 2020
0cf7869
Fix incorrect conditional setting of target
talldan Sep 2, 2020
f3eedfc
Specify all the deps
talldan Sep 2, 2020
94eb3b3
Add comment
talldan Sep 2, 2020
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 @@ -23,7 +23,7 @@ export default function BlockDraggableChip( { clientIds } ) {
const [ firstId ] = clientIds;
const blockName = getBlockName( firstId );

return getBlockType( blockName ).icon;
return getBlockType( blockName )?.icon;
},
[ clientIds ]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const BlockDraggable = ( {
cloneClassname,
onDragStart,
onDragEnd,
elementId,
} ) => {
const { srcRootClientId, isDraggable } = useSelect(
( select ) => {
Expand Down Expand Up @@ -68,7 +69,7 @@ const BlockDraggable = ( {
return (
<Draggable
cloneClassname={ cloneClassname }
elementId={ `block-${ clientIds[ 0 ] }` }
elementId={ elementId || `block-${ clientIds[ 0 ] }` }
transferData={ transferData }
onDragStart={ ( event ) => {
startDraggingBlocks( clientIds );
Expand Down
20 changes: 20 additions & 0 deletions packages/block-editor/src/components/block-navigation/appender.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { __experimentalTreeGridCell as TreeGridCell } from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { __, sprintf } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -20,6 +26,19 @@ export default function BlockNavigationAppender( {
terminatedLevels,
path,
} ) {
const isDragging = useSelect(
( select ) => {
const { isBlockBeingDragged, isAncestorBeingDragged } = select(
'core/block-editor'
);

return (
isBlockBeingDragged( parentBlockClientId ) ||
isAncestorBeingDragged( parentBlockClientId )
);
},
[ parentBlockClientId ]
);
const instanceId = useInstanceId( BlockNavigationAppender );
const descriptionId = `block-navigation-appender-row__description_${ instanceId }`;

Expand All @@ -32,6 +51,7 @@ export default function BlockNavigationAppender( {

return (
<BlockNavigationLeaf
className={ classnames( { 'is-dragging': isDragging } ) }
level={ level }
position={ position }
rowCount={ rowCount }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { forwardRef } from '@wordpress/element';

/**
Expand All @@ -9,6 +15,7 @@ import { forwardRef } from '@wordpress/element';
import { useBlockNavigationContext } from './context';
import BlockNavigationBlockSlot from './block-slot';
import BlockNavigationBlockSelectButton from './block-select-button';
import BlockDraggable from '../block-draggable';

const BlockNavigationBlockContents = forwardRef(
(
Expand All @@ -24,33 +31,85 @@ const BlockNavigationBlockContents = forwardRef(
ref
) => {
const {
__experimentalFeatures: withBlockNavigationSlots,
__experimentalFeatures,
blockDropTarget = {},
} = useBlockNavigationContext();

return withBlockNavigationSlots ? (
<BlockNavigationBlockSlot
ref={ ref }
className="block-editor-block-navigation-block-contents"
block={ block }
onClick={ onClick }
isSelected={ isSelected }
position={ position }
siblingBlockCount={ siblingBlockCount }
level={ level }
{ ...props }
/>
) : (
<BlockNavigationBlockSelectButton
ref={ ref }
className="block-editor-block-navigation-block-contents"
block={ block }
onClick={ onClick }
isSelected={ isSelected }
position={ position }
siblingBlockCount={ siblingBlockCount }
level={ level }
{ ...props }
/>
const { clientId } = block;

const rootClientId = useSelect(
( select ) =>
select( 'core/block-editor' ).getBlockRootClientId(
clientId
) || '',
[ clientId ]
);

const {
rootClientId: dropTargetRootClientId,
clientId: dropTargetClientId,
dropPosition,
} = blockDropTarget;

const isDroppingBefore =
dropTargetRootClientId === rootClientId &&
dropTargetClientId === clientId &&
dropPosition === 'top';
const isDroppingAfter =
dropTargetRootClientId === rootClientId &&
dropTargetClientId === clientId &&
dropPosition === 'bottom';
const isDroppingToInnerBlocks =
dropTargetRootClientId === clientId && dropPosition === 'inside';

const className = classnames(
'block-editor-block-navigation-block-contents',
{
'is-dropping-before': isDroppingBefore,
'is-dropping-after': isDroppingAfter,
'is-dropping-to-inner-blocks': isDroppingToInnerBlocks,
}
);

return (
<BlockDraggable
clientIds={ [ block.clientId ] }
elementId={ `block-navigation-block-${ block.clientId }` }
>
{ ( { isDraggable, onDraggableStart, onDraggableEnd } ) =>
__experimentalFeatures ? (
<BlockNavigationBlockSlot
ref={ ref }
className={ className }
block={ block }
onClick={ onClick }
isSelected={ isSelected }
position={ position }
siblingBlockCount={ siblingBlockCount }
level={ level }
draggable={ isDraggable && __experimentalFeatures }
onDragStart={ onDraggableStart }
onDragEnd={ onDraggableEnd }
{ ...props }
/>
) : (
<BlockNavigationBlockSelectButton
ref={ ref }
className={ className }
block={ block }
onClick={ onClick }
isSelected={ isSelected }
position={ position }
siblingBlockCount={ siblingBlockCount }
level={ level }
draggable={ isDraggable && __experimentalFeatures }
onDragStart={ onDraggableStart }
onDragEnd={ onDraggableEnd }
{ ...props }
/>
)
}
</BlockDraggable>
);
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ function BlockNavigationBlockSelectButton(
level,
tabIndex,
onFocus,
onDragStart,
onDragEnd,
draggable,
},
ref
) {
Expand Down Expand Up @@ -59,6 +62,9 @@ function BlockNavigationBlockSelectButton(
ref={ ref }
tabIndex={ tabIndex }
onFocus={ onFocus }
onDragStart={ onDragStart }
onDragEnd={ onDragEnd }
draggable={ draggable }
>
<BlockIcon icon={ blockType.icon } showColors />
{ blockDisplayName }
Expand Down
21 changes: 19 additions & 2 deletions packages/block-editor/src/components/block-navigation/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { __ } from '@wordpress/i18n';
import { moreVertical } from '@wordpress/icons';
import { useState, useRef, useEffect } from '@wordpress/element';
import { useDispatch } from '@wordpress/data';
import { useDispatch, useSelect } from '@wordpress/data';

/**
* Internal dependencies
Expand Down Expand Up @@ -45,10 +45,24 @@ export default function BlockNavigationBlock( {
const cellRef = useRef( null );
const [ isHovered, setIsHovered ] = useState( false );
const [ isFocused, setIsFocused ] = useState( false );
const { clientId } = block;
const isDragging = useSelect(
( select ) => {
const { isBlockBeingDragged, isAncestorBeingDragged } = select(
'core/block-editor'
);

return (
isBlockBeingDragged( clientId ) ||
isAncestorBeingDragged( clientId )
);
},
[ clientId ]
);

const { selectBlock: selectEditorBlock } = useDispatch(
'core/block-editor'
);
const { clientId } = block;

const hasSiblings = siblingBlockCount > 0;
const hasRenderedMovers = showBlockMovers && hasSiblings;
Expand All @@ -74,6 +88,7 @@ export default function BlockNavigationBlock( {
<BlockNavigationLeaf
className={ classnames( {
'is-selected': isSelected,
'is-dragging': isDragging,
} ) }
onMouseEnter={ () => setIsHovered( true ) }
onMouseLeave={ () => setIsHovered( false ) }
Expand All @@ -83,6 +98,8 @@ export default function BlockNavigationBlock( {
position={ position }
rowCount={ rowCount }
path={ path }
id={ `block-navigation-block-${ clientId }` }
data-block={ clientId }
>
<TreeGridCell
className="block-editor-block-navigation-block__contents-cell"
Expand Down
42 changes: 40 additions & 2 deletions packages/block-editor/src/components/block-navigation/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,55 @@ $tree-item-height: 36px;
// Use position relative for row animation.
position: relative;

&.is-dragging {
display: none;
}

.block-editor-block-navigation-block-contents {
display: flex;
align-items: center;
width: calc(100% - 0.8em);
width: 100%;
height: auto;
padding: $grid-unit-15 6px;
padding: $grid-unit-20 6px;
margin-top: auto;
margin-bottom: auto;
text-align: left;
color: $dark-gray-600;
border-radius: 2px;
position: relative;

&.is-dropping-before::before {
content: "";
position: absolute;
pointer-events: none;
transition: border-color 0.1s linear, border-style 0.1s linear, box-shadow 0.1s linear;
top: -2px;
right: 0;
left: 0;
border-top: 4px solid var(--wp-admin-theme-color);
}

&.is-dropping-after::before {
content: "";
position: absolute;
pointer-events: none;
transition: border-color 0.1s linear, border-style 0.1s linear, box-shadow 0.1s linear;
bottom: -2px;
right: 0;
left: 0;
border-bottom: 4px solid var(--wp-admin-theme-color);
}

&.is-dropping-to-inner-blocks::before {
content: "";
position: absolute;
pointer-events: none;
transition: border-color 0.1s linear, border-style 0.1s linear, box-shadow 0.1s linear;
bottom: -2px;
right: 0;
left: $icon-size;
border-bottom: 4px solid var(--wp-admin-theme-color);
}

.components-modal__content & {
padding-left: 0;
Expand Down
14 changes: 12 additions & 2 deletions packages/block-editor/src/components/block-navigation/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
*/

import { __experimentalTreeGrid as TreeGrid } from '@wordpress/components';
import { useMemo } from '@wordpress/element';
import { useMemo, useRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import BlockNavigationBranch from './branch';
import { BlockNavigationContext } from './context';
import useBlockNavigationDropZone from './use-block-navigation-drop-zone';

/**
* Wrap `BlockNavigationRows` with `TreeGrid`. BlockNavigationRows is a
Expand All @@ -24,17 +25,26 @@ export default function BlockNavigationTree( {
__experimentalFeatures,
...props
} ) {
const treeGridRef = useRef();
let blockDropTarget = useBlockNavigationDropZone( treeGridRef );

if ( ! __experimentalFeatures ) {
blockDropTarget = undefined;
}

const contextValue = useMemo(
() => ( {
__experimentalFeatures,
blockDropTarget,
} ),
[ __experimentalFeatures ]
[ __experimentalFeatures, blockDropTarget ]
);

return (
<TreeGrid
className="block-editor-block-navigation-tree"
aria-label={ __( 'Block navigation structure' ) }
ref={ treeGridRef }
>
<BlockNavigationContext.Provider value={ contextValue }>
<BlockNavigationBranch { ...props } />
Expand Down
Loading