Skip to content

Block Editor: Don't close inserter panel when inline quick inserter opens - #76241

Merged
t-hamano merged 8 commits into
WordPress:trunkfrom
Mustafabharmal:fix/inline-inserter-closes-panel
Aug 24, 2026
Merged

Block Editor: Don't close inserter panel when inline quick inserter opens#76241
t-hamano merged 8 commits into
WordPress:trunkfrom
Mustafabharmal:fix/inline-inserter-closes-panel

Conversation

@Mustafabharmal

Copy link
Copy Markdown
Contributor

What?

Closes #72297.

When the block inserter panel (sidebar) is open and a user clicks the inline block appender (in-between inserter), the panel was being force-closed.

Why?

QuickInserter had a useEffect that called setInserterIsOpened(false) on every mount:

useEffect( () => {
    if ( setInserterIsOpened ) {
        setInserterIsOpened( false );
    }
}, [ setInserterIsOpened ] );

This unconditionally closed the inserter sidebar panel any time the inline quick inserter opened, even when the user had intentionally opened the panel beforehand.

How?

Remove the useEffect. The inline quick inserter and the sidebar panel can coexist without conflict. The existing "Browse All" button already handles opening the sidebar panel with the correct insertion context when the user explicitly wants to expand to it.

Testing Instructions

  1. Open a post in the block editor.
  2. Open the block inserter panel (the + button in the toolbar that opens the sidebar).
  3. Hover between two blocks to reveal the inline block appender and click it.
  4. Expected (after fix): The inserter panel stays open, the inline quick inserter popover appears normally, and the inline appender continues to work after dismissing.
  5. Before fix: The inserter panel would close immediately when the inline appender was clicked.

Screenshots or screencast

Before:

Before.Inserter.Fix.mov

After:

After.Inserter.Fix.mov

@Mustafabharmal
Mustafabharmal requested a review from ellatrix as a code owner March 6, 2026 11:27
@github-actions github-actions Bot added the [Package] Block editor /packages/block-editor label Mar 6, 2026
@github-actions

github-actions Bot commented Mar 6, 2026

Copy link
Copy Markdown

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 props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @finlay-x.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: finlay-x.

Co-authored-by: Mustafabharmal <mustafabharmal@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: jeryj <jeryj@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@Mamaduka Mamaduka added [Type] Bug An existing feature does not function as intended [Feature] Inserter The main way to insert blocks using the + button in the editing interface labels Apr 8, 2026
@Mamaduka

Mamaduka commented Apr 8, 2026

Copy link
Copy Markdown
Member

Thanks for working on this, @Mustafabharmal!

Do you mind rebasing the branch onto the latest trunk?

@Mustafabharmal
Mustafabharmal force-pushed the fix/inline-inserter-closes-panel branch from b187a7f to 3cc8414 Compare April 9, 2026 10:25
@Mamaduka

Mamaduka commented Apr 9, 2026

Copy link
Copy Markdown
Member

Thanks, @Mustafabharmal!

While this fixes the mentioned issue, it introduces an unwanted side effect. Clicking on the 'Browse all' button now does nothing, and it seems like the action is broken.

Maybe we revisit what the expected behavior should be here. cc @jeryj, @t-hamano

Screenshot

CleanShot.2026-04-09.at.15.34.50.mp4

@jeryj

jeryj commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Thanks for looking at this @Mustafabharmal!

I believe closing the sidebar inserter when clicking an on-canvas inserter is an intentional design choice. To fix the bug in #72297, I think we should:

  • close the sidebar inserter
  • keep the inbetween quick inserter mounted

What is making the bug that's making the inbetween quick inserter unmount?

@t-hamano

Copy link
Copy Markdown
Contributor

What is making the bug that's making the inbetween quick inserter unmount?

My investigation yielded the following results:

BlockTypesTabPanel is mounted when the sidebar inserter is opened:

When the quickinserter is opened, this effect closes the sidebar inserter:

useEffect( () => {
if ( setInserterIsOpened ) {
setInserterIsOpened( false );
}
}, [ setInserterIsOpened ] );

BlockTypesTabPanel is unmounted, and this effect is triggered:

// Hide block preview on unmount.
useEffect( () => () => onHover( null ), [] );

onToggleInsertionPoint is triggered here:

// Hide block preview on unmount.
useEffect( () => () => onHover( null ), [] );

hideInsertionPoint() unintentionally unmounts the Quick Inserter panel:


I'm not sure what the best approach is yet, but checking __unstableWithInserter might be one way to go.

diff --git a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
index a79949085b8..f28b8d9dee4 100644
--- a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
+++ b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
@@ -75,6 +75,7 @@ function useInsertionPoint( {
                getSelectedBlock,
                getClosestAllowedInsertionPoint,
                isBlockInsertionPointVisible,
+               getBlockInsertionPoint,
        } = unlock( useSelect( blockEditorStore ) );
        const { destinationRootClientId, destinationIndex } = useSelect(
                ( select ) => {
@@ -226,12 +227,18 @@ function useInsertionPoint( {
                                        );
                                }
                        } else {
-                               hideInsertionPoint();
+                               // Don't hide the insertion point owned by the in-between inserter.
+                               const insertionPoint = getBlockInsertionPoint();
+                               console.log(insertionPoint);
+                               if ( ! insertionPoint?.__unstableWithInserter ) {
+                                       hideInsertionPoint();
+                               }
                        }
                },
                [
                        getClosestAllowedInsertionPoint,
                        isBlockInsertionPointVisible,
+                       getBlockInsertionPoint,
                        showInsertionPoint,
                        hideInsertionPoint,
                        destinationRootClientId,

@Mustafabharmal

Copy link
Copy Markdown
Contributor Author

Thanks for the review, everyone. I’ve updated the implementation based on the feedback.

@t-hamano

Copy link
Copy Markdown
Contributor

As far as I can see, the code looks good.

@Mustafabharmal, can you also add an e2e test? Perhaps the most suitable file would be test/e2e/specs/editor/various/inserting-blocks.spec.js.

@Mamaduka

Copy link
Copy Markdown
Member

@Mustafabharmal, I see you went in a different direction using ref for bookkeeping instead of insertionPoint?.__unstableWithInserter? Was there a specific reason for it?

The general problem with using refs to track values is that they can become stale, whereas selectors have the latest data.

@Mustafabharmal

Copy link
Copy Markdown
Contributor Author

@Mustafabharmal, I see you went in a different direction using ref for bookkeeping instead of insertionPoint?.__unstableWithInserter? Was there a specific reason for it?

The general problem with using refs to track values is that they can become stale, whereas selectors have the latest data.

Yes @Mamaduka , there were a couple of reasons behind the initial shift to the ref-based approach.

The main reason was to keep track of whether the insertion point was opened by the block inserter itself, rather than relying only on the current insertion cue. There are also some cues, such as drop-zone cues using operation: 'replace', that don't have __unstableWithInserter, so I initially thought the ref would provide more explicit ownership tracking.

However, after revisiting the implementation based on your feedback, I agree that the ref can become stale. In particular, use-in-between-inserter can update the insertion point independently, so the ref may no longer represent the current store state. That can cause the cleanup in the inserter to hide a cue that it no longer owns.

Using getBlockInsertionPoint() gives us the current state at the time of cleanup and allows us to check __unstableWithInserter reliably. I’ve therefore updated the approach to use the selector instead of the ref.

Thanks for pointing this out, I think the selector-based approach is safer here.

@t-hamano

Copy link
Copy Markdown
Contributor

I found a small bug. Please try the following steps:

  1. Insert two blocks.
  2. Move your mouse between the two blocks.
  3. An in-between inserter will appear.
  4. Click the "Add block" button.
  5. Open the inserter sidebar.
    • Actual: The In-between inserter is still displayed. The in-between inserter remains visible even when hovering over blocks in the inserter sidebar.
    • Expected: The In-between inserter should only be displayed when hovering over a block within the inserter sidebar.
in-between.mp4

As far as I tested, the following changes fixed the issue, but we need to perform smoke tests to ensure no other problems arise.

diff --git a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js b/packages/block-editor
/src/components/inserter/hooks/use-insertion-point.js
index b78f268f702..a1a66b4c05c 100644
--- a/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
+++ b/packages/block-editor/src/components/inserter/hooks/use-insertion-point.js
@@ -67,7 +67,6 @@ function useInsertionPoint( {
        const {
                getSelectedBlock,
                getClosestAllowedInsertionPoint,
-               isBlockInsertionPointVisible,
                getBlockInsertionPoint,
        } = unlock( useSelect( blockEditorStore ) );
        const { destinationRootClientId, destinationIndex } = useSelect(
@@ -202,7 +201,7 @@ function useInsertionPoint( {
 
        const onToggleInsertionPoint = useCallback(
                ( item ) => {
-                       if ( item && ! isBlockInsertionPointVisible() ) {
+                       if ( item ) {
                                const allowedDestinationRootClientId =
                                        getClosestAllowedInsertionPoint(
                                                item.name,
@@ -230,7 +229,6 @@ function useInsertionPoint( {
                },
                [
                        getClosestAllowedInsertionPoint,
-                       isBlockInsertionPointVisible,
                        getBlockInsertionPoint,
                        showInsertionPoint,
                        hideInsertionPoint,

@t-hamano t-hamano left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good from my end 👍

@Mamaduka, do you have any concerns?

@Mamaduka

Copy link
Copy Markdown
Member

Looks good; just need changelog conflict resolution.

@t-hamano
t-hamano merged commit ec35342 into WordPress:trunk Aug 24, 2026
55 of 65 checks passed
@github-actions github-actions Bot added this to the Gutenberg 23.9 milestone Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Inserter The main way to insert blocks using the + button in the editing interface [Package] Block editor /packages/block-editor [Type] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Opening the block inserter popover when the block inserter panel is open completely disables/breaks the inline block inserter button

4 participants