From 4a4d1946939bf3cd986de651bc67b56f289e1ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= <4710635+ellatrix@users.noreply.github.com> Date: Thu, 10 Jun 2021 17:04:37 +0300 Subject: [PATCH] Drop indicator: show around dragged block and show above selected block for file drop (#31896) --- .../block-list/use-in-between-inserter.js | 16 ++++ .../components/block-tools/block-popover.js | 22 +++++- .../components/block-tools/insertion-point.js | 75 +++++++------------ .../src/components/block-tools/style.scss | 5 ++ .../components/use-block-drop-zone/index.js | 16 ++-- .../use-block-drop-zone/test/index.js | 42 ----------- .../compose/src/hooks/use-drop-zone/index.js | 47 +++++++++--- 7 files changed, 111 insertions(+), 112 deletions(-) diff --git a/packages/block-editor/src/components/block-list/use-in-between-inserter.js b/packages/block-editor/src/components/block-list/use-in-between-inserter.js index 0dfdab359d7a7..618811ec91ba6 100644 --- a/packages/block-editor/src/components/block-list/use-in-between-inserter.js +++ b/packages/block-editor/src/components/block-list/use-in-between-inserter.js @@ -14,12 +14,17 @@ import { InsertionPointOpenRef } from '../block-tools/insertion-point'; export function useInBetweenInserter() { const openRef = useContext( InsertionPointOpenRef ); + const hasReducedUI = useSelect( + ( select ) => select( blockEditorStore ).getSettings().hasReducedUI, + [] + ); const { getBlockListSettings, getBlockRootClientId, getBlockIndex, isBlockInsertionPointVisible, isMultiSelecting, + getSelectedBlockClientIds, } = useSelect( blockEditorStore ); const { showInsertionPoint, hideInsertionPoint } = useDispatch( blockEditorStore @@ -27,6 +32,10 @@ export function useInBetweenInserter() { return useRefEffect( ( node ) => { + if ( hasReducedUI ) { + return; + } + function onMouseMove( event ) { if ( openRef.current ) { return; @@ -98,6 +107,12 @@ export function useInBetweenInserter() { return; } + // Don't show the inserter when hovering above (conflicts with + // block toolbar) or inside selected block(s). + if ( getSelectedBlockClientIds().includes( clientId ) ) { + return; + } + const elementRect = element.getBoundingClientRect(); if ( @@ -145,6 +160,7 @@ export function useInBetweenInserter() { isMultiSelecting, showInsertionPoint, hideInsertionPoint, + getSelectedBlockClientIds, ] ); } diff --git a/packages/block-editor/src/components/block-tools/block-popover.js b/packages/block-editor/src/components/block-tools/block-popover.js index dc803f7670aba..8371cfff9bbba 100644 --- a/packages/block-editor/src/components/block-tools/block-popover.js +++ b/packages/block-editor/src/components/block-tools/block-popover.js @@ -64,6 +64,24 @@ function BlockPopover( { hasFixedToolbar, lastClientId, } = useSelect( selector, [] ); + const isInsertionPointVisible = useSelect( + ( select ) => { + const { + isBlockInsertionPointVisible, + getBlockInsertionPoint, + getBlockOrder, + } = select( blockEditorStore ); + + if ( ! isBlockInsertionPointVisible() ) { + return false; + } + + const insertionPoint = getBlockInsertionPoint(); + const order = getBlockOrder( insertionPoint.rootClientId ); + return order[ insertionPoint.index ] === clientId; + }, + [ clientId ] + ); const isLargeViewport = useViewportMatch( 'medium' ); const [ isToolbarForced, setIsToolbarForced ] = useState( false ); const [ isInserterShown, setIsInserterShown ] = useState( false ); @@ -184,7 +202,9 @@ function BlockPopover( { position={ popoverPosition } focusOnMount={ false } anchorRef={ anchorRef } - className="block-editor-block-list__block-popover" + className={ classnames( 'block-editor-block-list__block-popover', { + 'is-insertion-point-visible': isInsertionPointVisible, + } ) } __unstableStickyBoundaryElement={ stickyBoundaryElement } // Render in the old slot if needed for backward compatibility, // otherwise render in place (not in the the default popover slot). diff --git a/packages/block-editor/src/components/block-tools/insertion-point.js b/packages/block-editor/src/components/block-tools/insertion-point.js index 134430c301a61..b836beba7d3ae 100644 --- a/packages/block-editor/src/components/block-tools/insertion-point.js +++ b/packages/block-editor/src/components/block-tools/insertion-point.js @@ -36,7 +36,6 @@ function InsertionPointPopover( { const ref = useRef(); const { orientation, - isHidden, previousClientId, nextClientId, rootClientId, @@ -45,47 +44,36 @@ function InsertionPointPopover( { const { getBlockOrder, getBlockListSettings, - getMultiSelectedBlockClientIds, - getSelectedBlockClientId, - hasMultiSelection, - getSettings, getBlockInsertionPoint, + isBlockBeingDragged, + getPreviousBlockClientId, + getNextBlockClientId, } = select( blockEditorStore ); const insertionPoint = getBlockInsertionPoint(); const order = getBlockOrder( insertionPoint.rootClientId ); - const targetClientId = order[ insertionPoint.index - 1 ]; - const targetRootClientId = insertionPoint.rootClientId; - const blockOrder = getBlockOrder( targetRootClientId ); - if ( ! blockOrder.length ) { + + if ( ! order.length ) { return {}; } - const previous = targetClientId - ? targetClientId - : blockOrder[ blockOrder.length - 1 ]; - const isLast = previous === blockOrder[ blockOrder.length - 1 ]; - const next = isLast - ? null - : blockOrder[ blockOrder.indexOf( previous ) + 1 ]; - const { hasReducedUI } = getSettings(); - const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(); - const selectedBlockClientId = getSelectedBlockClientId(); - const blockOrientation = - getBlockListSettings( targetRootClientId )?.orientation || - 'vertical'; + + let _previousClientId = order[ insertionPoint.index - 1 ]; + let _nextClientId = order[ insertionPoint.index ]; + + while ( isBlockBeingDragged( _previousClientId ) ) { + _previousClientId = getPreviousBlockClientId( _previousClientId ); + } + + while ( isBlockBeingDragged( _nextClientId ) ) { + _nextClientId = getNextBlockClientId( _nextClientId ); + } return { - previousClientId: previous, - nextClientId: next, - isHidden: - hasReducedUI || - ( hasMultiSelection() - ? next && multiSelectedBlockClientIds.includes( next ) - : next && - blockOrientation === 'vertical' && - next === selectedBlockClientId ), - orientation: blockOrientation, - clientId: targetClientId, - rootClientId: targetRootClientId, + previousClientId: _previousClientId, + nextClientId: _nextClientId, + orientation: + getBlockListSettings( insertionPoint.rootClientId ) + ?.orientation || 'vertical', + rootClientId: insertionPoint.rootClientId, isInserterShown: insertionPoint?.__unstableWithInserter, }; }, [] ); @@ -193,14 +181,7 @@ function InsertionPointPopover( { // Only show the inserter when there's a `nextElement` (a block after the // insertion point). At the end of the block list the trailing appender // should serve the purpose of inserting blocks. - const showInsertionPointInserter = - ! isHidden && nextElement && isInserterShown; - - // Show the indicator if the insertion point inserter is visible, or if - // the `showInsertionPoint` state is `true`. The latter is generally true - // when hovering blocks for insertion in the block library. - const showInsertionPointIndicator = - showInsertionPointInserter || ! isHidden; + const showInsertionPointInserter = nextElement && isInserterShown; /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ // While ideally it would be enough to capture the @@ -231,9 +212,7 @@ function InsertionPointPopover( { } ) } style={ style } > - { showInsertionPointIndicator && ( -
- ) } + { showInsertionPointInserter && (