diff --git a/packages/block-editor/src/components/block-list/insertion-point.js b/packages/block-editor/src/components/block-list/insertion-point.js index e393710dc5a47c..db2653b031bc7e 100644 --- a/packages/block-editor/src/components/block-list/insertion-point.js +++ b/packages/block-editor/src/components/block-list/insertion-point.js @@ -23,7 +23,11 @@ import { isRTL } from '@wordpress/i18n'; import Inserter from '../inserter'; import { getBlockDOMNode } from '../../utils/dom'; -function InsertionPointInserter( { clientId, setIsInserterForced } ) { +function InsertionPointInserter( { + clientId, + rootClientId, + setIsInserterForced, +} ) { return (
setIsInserterForced( false ) } @@ -43,7 +48,7 @@ function InsertionPointInserter( { clientId, setIsInserterForced } ) { function InsertionPointPopover( { clientId, - rootClientId, + selectedRootClientId, isInserterShown, isInserterForced, setIsInserterForced, @@ -53,7 +58,14 @@ function InsertionPointPopover( { const { selectBlock } = useDispatch( 'core/block-editor' ); const ref = useRef(); - const { previousElement, nextElement, orientation, isHidden } = useSelect( + const { + previousElement, + nextElement, + orientation, + isHidden, + nextClientId, + rootClientId, + } = useSelect( ( select ) => { const { getBlockOrder, @@ -67,15 +79,18 @@ function InsertionPointPopover( { const { ownerDocument } = containerRef.current; const targetRootClientId = clientId ? getBlockRootClientId( clientId ) - : rootClientId; + : selectedRootClientId; const blockOrder = getBlockOrder( targetRootClientId ); - if ( blockOrder.length < 2 ) { + if ( ! blockOrder.length ) { return {}; } - const next = clientId + const previous = clientId ? clientId : blockOrder[ blockOrder.length - 1 ]; - const previous = blockOrder[ blockOrder.indexOf( next ) - 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(); @@ -86,53 +101,77 @@ function InsertionPointPopover( { return { previousElement: getBlockDOMNode( previous, ownerDocument ), nextElement: getBlockDOMNode( next, ownerDocument ), + nextClientId: next, isHidden: hasReducedUI || ( hasMultiSelection() - ? multiSelectedBlockClientIds.includes( clientId ) - : blockOrientation === 'vertical' && - clientId === selectedBlockClientId ), + ? next && multiSelectedBlockClientIds.includes( next ) + : next && + blockOrientation === 'vertical' && + next === selectedBlockClientId ), orientation: blockOrientation, + rootClientId: targetRootClientId, }; }, - [ clientId, rootClientId ] + [ clientId, selectedRootClientId ] ); const style = useMemo( () => { - if ( ! previousElement || ! nextElement ) { + if ( ! previousElement ) { return {}; } const previousRect = previousElement.getBoundingClientRect(); - const nextRect = nextElement.getBoundingClientRect(); - - return orientation === 'vertical' - ? { - width: previousElement.offsetWidth, - height: nextRect.top - previousRect.bottom, - } - : { - width: isRTL() - ? previousRect.left - nextRect.right - : nextRect.left - previousRect.right, - height: previousElement.offsetHeight, - }; + const nextRect = nextElement + ? nextElement.getBoundingClientRect() + : null; + + if ( orientation === 'vertical' ) { + return { + width: previousElement.offsetWidth, + height: nextRect ? nextRect.top - previousRect.bottom : 0, + }; + } + + let width = 0; + if ( nextElement ) { + width = isRTL() + ? previousRect.left - nextRect.right + : nextRect.left - previousRect.right; + } + + return { + width, + height: previousElement.offsetHeight, + }; }, [ previousElement, nextElement ] ); const getAnchorRect = useCallback( () => { const previousRect = previousElement.getBoundingClientRect(); - const nextRect = nextElement.getBoundingClientRect(); + const nextRect = nextElement + ? nextElement.getBoundingClientRect() + : null; if ( orientation === 'vertical' ) { return { top: previousRect.bottom, left: previousRect.left, right: previousRect.right, - bottom: nextRect.top, + bottom: nextRect ? nextRect.top : previousRect.bottom, + }; + } + + if ( isRTL() ) { + return { + top: previousRect.top, + left: nextRect ? nextRect.right : previousRect.left, + right: previousRect.left, + bottom: previousRect.bottom, }; } + return { top: previousRect.top, - left: isRTL() ? nextRect.right : previousRect.right, - right: isRTL() ? previousRect.left : nextRect.left, + left: previousRect.right, + right: nextRect ? nextRect.left : previousRect.right, bottom: previousRect.bottom, }; }, [ previousElement, nextElement ] ); @@ -147,8 +186,8 @@ function InsertionPointPopover( { ); function onClick( event ) { - if ( event.target === ref.current ) { - selectBlock( clientId, -1 ); + if ( event.target === ref.current && nextClientId ) { + selectBlock( nextClientId, -1 ); } } @@ -192,7 +231,8 @@ function InsertionPointPopover( { ) } { ! isHidden && ( isInserterShown || isInserterForced ) && ( ) } @@ -228,7 +268,7 @@ export default function useInsertionPoint( ref ) { getBlockListSettings: _getBlockListSettings, isMultiSelecting: _isMultiSelecting(), isInserterVisible: isBlockInsertionPointVisible(), - selectedClientId: order[ insertionPoint.index ], + selectedClientId: order[ insertionPoint.index - 1 ], selectedRootClientId: insertionPoint.rootClientId, }; }, [] ); @@ -261,16 +301,20 @@ export default function useInsertionPoint( ref ) { const rect = event.target.getBoundingClientRect(); const offsetTop = event.clientY - rect.top; const offsetLeft = event.clientX - rect.left; - let element = Array.from( event.target.children ).find( - ( blockEl ) => { - return ( - ( orientation === 'vertical' && - blockEl.offsetTop > offsetTop ) || - ( orientation === 'horizontal' && - blockEl.offsetLeft > offsetLeft ) - ); - } - ); + + const children = Array.from( event.target.children ); + const nextElement = children.find( ( blockEl ) => { + return ( + ( orientation === 'vertical' && + blockEl.offsetTop > offsetTop ) || + ( orientation === 'horizontal' && + blockEl.offsetLeft > offsetLeft ) + ); + } ); + + let element = nextElement + ? children[ children.indexOf( nextElement ) - 1 ] + : children[ children.length - 1 ]; if ( ! element ) { return; @@ -337,7 +381,7 @@ export default function useInsertionPoint( ref ) { clientId={ isInserterVisible ? selectedClientId : inserterClientId } - rootClientId={ selectedRootClientId } + selectedRootClientId={ selectedRootClientId } isInserterShown={ isInserterShown } isInserterForced={ isInserterForced } setIsInserterForced={ ( value ) => { diff --git a/packages/e2e-tests/specs/widgets/adding-widgets.test.js b/packages/e2e-tests/specs/widgets/adding-widgets.test.js index 3fd2fe3c744a5a..7db8bb38e1cc0c 100644 --- a/packages/e2e-tests/specs/widgets/adding-widgets.test.js +++ b/packages/e2e-tests/specs/widgets/adding-widgets.test.js @@ -64,7 +64,6 @@ describe( 'Widgets screen', () => { return addParagraphBlock; } - /* async function expectInsertionPointIndicatorToBeBelowLastBlock( widgetArea ) { @@ -82,7 +81,6 @@ describe( 'Widgets screen', () => { insertionPointIndicatorBoundingBox.y > lastBlockBoundingBox.y ).toBe( true ); } - */ async function getInlineInserterButton() { return await page.waitForSelector( @@ -124,9 +122,9 @@ describe( 'Widgets screen', () => { addParagraphBlock = await getParagraphBlockInGlobalInserter(); await addParagraphBlock.hover(); - /*await expectInsertionPointIndicatorToBeBelowLastBlock( + await expectInsertionPointIndicatorToBeBelowLastBlock( firstWidgetArea - );*/ + ); await addParagraphBlock.click(); await page.keyboard.type( 'Second Paragraph' );