diff --git a/packages/block-editor/src/components/block-tools/selected-block-popover.js b/packages/block-editor/src/components/block-tools/selected-block-popover.js index 06b2b519b02fdb..652c04efe6aed5 100644 --- a/packages/block-editor/src/components/block-tools/selected-block-popover.js +++ b/packages/block-editor/src/components/block-tools/selected-block-popover.js @@ -16,7 +16,6 @@ import { useViewportMatch } from '@wordpress/compose'; /** * Internal dependencies */ -import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; import BlockSelectionButton from './block-selection-button'; import BlockContextualToolbar from './block-contextual-toolbar'; import { store as blockEditorStore } from '../../store'; @@ -115,10 +114,9 @@ function SelectedBlockPopover( { // to it when re-mounting. const initialToolbarItemIndexRef = useRef(); - const selectedBlockElement = useBlockElement( clientId ); const popoverProps = useBlockToolbarPopoverProps( { contentElement: __unstableContentRef?.current, - selectedBlockElement, + clientId, } ); if ( ! shouldShowBreadcrumb && ! shouldShowContextualToolbar ) { diff --git a/packages/block-editor/src/components/block-tools/use-block-toolbar-popover-props.js b/packages/block-editor/src/components/block-tools/use-block-toolbar-popover-props.js index b11ddd79a743a3..7c5eb35c6052fe 100644 --- a/packages/block-editor/src/components/block-tools/use-block-toolbar-popover-props.js +++ b/packages/block-editor/src/components/block-tools/use-block-toolbar-popover-props.js @@ -1,8 +1,15 @@ /** * WordPress dependencies */ +import { useSelect } from '@wordpress/data'; import { useEffect, useState } from '@wordpress/element'; +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; +import { __unstableUseBlockElement as useBlockElement } from '../block-list/use-block-props/use-block-refs'; + const TOOLBAR_HEIGHT = 72; const DEFAULT_PROPS = { __unstableForcePosition: true, __unstableShift: true }; const RESTRICTED_HEIGHT_PROPS = { @@ -31,19 +38,31 @@ function getProps( contentElement, selectedBlockElement ) { * Determines the desired popover positioning behavior, returning a set of appropriate props. * * @param {Object} elements - * @param {Element} elements.contentElement The DOM element that represents the editor content or canvas. - * @param {Element} elements.selectedBlockElement The DOM element that represents the first selected block. + * @param {Element} elements.contentElement The DOM element that represents the editor content or canvas. + * @param {string} elements.clientId The clientId of the first selected block. * * @return {Object} The popover props used to determine the position of the toolbar. */ export default function useBlockToolbarPopoverProps( { contentElement, - selectedBlockElement, + clientId, } ) { + const selectedBlockElement = useBlockElement( clientId ); const [ props, setProps ] = useState( getProps( contentElement, selectedBlockElement ) ); + const blockIndex = useSelect( + ( select ) => select( blockEditorStore ).getBlockIndex( clientId ), + [ clientId ] + ); + // Update the toolbar position if the block moves. + useEffect( () => { + setProps( getProps( contentElement, selectedBlockElement ) ); + }, [ blockIndex ] ); + + // Update the toolbar position if the window resizes, or the + // selected element changes. useEffect( () => { if ( ! contentElement || ! selectedBlockElement ) { return; @@ -52,11 +71,7 @@ export default function useBlockToolbarPopoverProps( { const updateProps = () => setProps( getProps( contentElement, selectedBlockElement ) ); - // Update whenever the content or selectedBlock elements change. updateProps(); - - // Update on window resize - wrapping can change the amount of space - // above a block, and result in the toolbar position needing to change. const view = contentElement?.ownerDocument?.defaultView; view?.addEventHandler?.( 'resize', updateProps );