Block Toolbar: Prevent position shifts when using mover control#77798
Block Toolbar: Prevent position shifts when using mover control#77798shrivastavanolo wants to merge 2 commits intoWordPress:trunkfrom
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
| const debouncedRecompute = useCallback( () => { | ||
| window.requestAnimationFrame( () => forceRecomputePopoverDimensions() ); | ||
| }, [ forceRecomputePopoverDimensions ] ); |
There was a problem hiding this comment.
Thanks for the feedback! Removed the useCallback wrapper and inlined the requestAnimationFrame without the extra memoization.
…o prevent toolbar position shift
2b24937 to
4cd2c44
Compare
There was a problem hiding this comment.
Pull request overview
This PR aims to stabilize the block toolbar’s positioning during block move animations by deferring popover dimension recomputation so it doesn’t react mid-frame to frequent transform attribute updates.
Changes:
- Adjusted the
MutationObserverhandler inBlockPopoverto deferforceRecomputePopoverDimensionsviarequestAnimationFrame.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const observer = new window.MutationObserver( () => | ||
| window.requestAnimationFrame( () => | ||
| forceRecomputePopoverDimensions() | ||
| ) | ||
| ); |
|
Thank you for working on this! While this PR seems to fix the issue, it's likely fixing a symptom, rather than curing the root cause. Here is a more detailed explanation of what's going on IMOThe What's happening on
That continuous teardown/rebuild fighting with the in-flight If that analysis is right, then the right fix is most likely to remove the Can we try just removing the Example code changes import {
forwardRef,
useMemo,
- useReducer,
- useLayoutEffect,
} from '@wordpress/element';
...
-const MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER;
-
function BlockPopover( ... ) {
- const [
- popoverDimensionsRecomputeCounter,
- forceRecomputePopoverDimensions,
- ] = useReducer(
- ( s ) => ( s + 1 ) % MAX_POPOVER_RECOMPUTE_COUNTER,
- 0
- );
-
- useLayoutEffect( () => {
- if ( ! selectedElement ) {
- return;
- }
- const observer = new window.MutationObserver( () =>
- window.requestAnimationFrame( () =>
- forceRecomputePopoverDimensions()
- )
- );
- observer.observe( selectedElement, { attributes: true } );
- return () => observer.disconnect();
- }, [ selectedElement ] );
const popoverAnchor = useMemo( () => {
if (
- popoverDimensionsRecomputeCounter < 0 ||
! selectedElement ||
( bottomClientId && ! lastSelectedElement )
) {
return undefined;
}
return {
getBoundingClientRect() { ... },
contextElement: selectedElement,
};
- }, [ popoverDimensionsRecomputeCounter, selectedElement, bottomClientId, lastSelectedElement ] );
+ }, [ selectedElement, bottomClientId, lastSelectedElement ] );If removing it does regress some scenario, the next-best alternative is to keep the observer but stop having it change |
What?
Closes #61435
Stops the block toolbar from jumping around when using the mover controls.
Why?
When a block is moved, its transform attribute updates on every animation frame. The toolbar was repositioning itself on each of those updates — mid-animation — causing it to shift erratically.
How?
Wrapped the popover recompute in requestAnimationFrame so it waits for the current animation frame to finish before repositioning, instead of firing on every transform change.
Testing Instructions
Screenshots or screencast
Before
before.mov
After
after.mov
Use of AI Tools
Claude (Anthropic) was used to help draft this PR. All changes were reviewed manually.