Skip to content

Dropdown: Close popover when focus moves into an unrelated dialog - #82170

Closed
wprashed wants to merge 9 commits into
WordPress:trunkfrom
wprashed:fix/82124-dropdown-popover-stuck-on-dialog-open
Closed

Dropdown: Close popover when focus moves into an unrelated dialog#82170
wprashed wants to merge 9 commits into
WordPress:trunkfrom
wprashed:fix/82124-dropdown-popover-stuck-on-dialog-open

Conversation

@wprashed

Copy link
Copy Markdown
Contributor

Fixes #82124

Description

When a Dropdown popover is open (e.g. "Transform to" block switcher popover on Custom HTML block) and the user opens an unrelated dialog (e.g. clicking "Edit code" on the toolbar), the Dropdown previously kept the popover stuck open behind the modal dialog.

Cause

Dropdown's closeIfFocusOutside checked if focus moved into any [role="dialog"], treating any dialog on the page as a reason to preserve presence. However, it couldn't distinguish whether the dialog was launched from inside the dropdown itself (e.g. Preferences modal from Options menu) vs launched by an unrelated element elsewhere on the page.

Solution

This PR updates Dropdown to:

  1. Track whether the last user interaction (pointerdown or focusin) occurred inside the Dropdown container or popover.
  2. Ignore focusin events landing directly inside a [role="dialog"], because focus moving into a dialog on mount is the consequence of an action, not the user interaction that triggered it.
  3. Close the popover if focus moves into a dialog that was NOT launched from inside the dropdown itself.

Testing Instructions

  1. Insert a Custom HTML block with some content (e.g. <h1>Test</h1>).
  2. Click the block switcher icon in the block toolbar to open the "Transform to" popover.
  3. Click "Edit code" on the block toolbar while the "Transform to" popover is open.
  4. Verify that the "Edit code" modal opens and the "Transform to" popover cleanly closes (no longer stuck open behind the modal).
  5. Open the Options menu (three dots in editor header) and click "Preferences".
  6. Verify that the Options menu popover preserves presence while the Preferences modal is active.

wprashed and others added 6 commits August 18, 2026 16:52
When the accordion content style was changed to support in-browser search
via `hidden="until-found"` (WordPress#74744), the browser applies
`content-visibility: hidden`. Because `content-visibility: hidden` hides
contents without removing the container box model, any user- or theme-defined
padding on the Accordion Panel block produced an empty gap below the title
when the accordion was closed.

This resets `padding-block: 0 !important` on `.wp-block-accordion-panel[hidden]`
so the closed panel occupies no vertical space while preserving the full padding
when the panel is open.

Fixes WordPress#65900 (Trac WordPress#65900).
Addresses review feedback by ensuring borders and box shadows are also
reset when the accordion panel is hidden, along with padding.
Fixes WordPress#82124

When a Dropdown popover is open and focus moves into a `[role="dialog"]`,
Dropdown previously preserved presence for any dialog on the page, even if
the dialog was launched from an unrelated element (such as clicking 'Edit code'
on the Custom HTML toolbar).

This updates Dropdown to track whether the last user interaction (pointerdown
or focusin) occurred inside the Dropdown container/popover. If focus moves into
a dialog that was NOT launched from inside the dropdown, the popover closes cleanly.
@github-actions

github-actions Bot commented Aug 28, 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.

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

Co-authored-by: wprashed <wprashed@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: himanshupathak95 <abcd95@git.wordpress.org>

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

@wprashed
wprashed force-pushed the fix/82124-dropdown-popover-stuck-on-dialog-open branch from dca3257 to 4f3fb40 Compare August 28, 2026 09:39
@github-actions github-actions Bot removed the [Package] Block library /packages/block-library label Aug 28, 2026
Comment on lines +54 to +55
const popoverRef = useRef< HTMLDivElement >( null );
const mergedPopoverRef = useMergeRefs( [ popoverRef, popoverProps?.ref ] );

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.

popoverProps.ref is excluded by the public type, so this currently fails type checking. It should not be added solely for internal bookkeeping. The interaction origin can instead be tracked through capture handlers on the Dropdown wrapper, which also receive events from the portaled Popover. This removes the need for popoverRef and useMergeRefs.

Comment on lines +77 to +85
// Ignore focusin events landing inside a [role="dialog"], because
// focus moving into a dialog (e.g. on modal mount) is the consequence
// of an action, not the user interaction that triggered it.
if (
event.type === 'focusin' &&
( target as Element ).closest?.( '[role="dialog"]' )
) {
return;
}

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.

The handler ignores all focus entering a dialog. But a keyboard user can therefore Tab into an existing unrelated non-modal dialog and leave the dropdown open.

We should preserve the dropdown only when the dialog focus follows an activation from inside it (and ideally cover this keyboard path in the tests)

expect( screen.queryByText( 'test' ) ).not.toBeInTheDocument();
} );

it( 'should close the dropdown when focus moves into an unrelated dialog', async () => {

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.

some feedback:

  • I believe this external-dialog test also would also pass on trunk without this PR's fix.
  • includeHidden is unsupported and fails type checking. We could use hidden: true or assert onClose and DOM removal.
  • We should also verify that the related dialog returns focus to its dropdown trigger after closing.

After these changes, let's confirm the test fails on the base and passes with the fix.

Comment thread packages/components/CHANGELOG.md Outdated

### Bug Fixes

- `Dropdown`: Close popover when focus moves to an unrelated dialog outside the dropdown ([#82124](https://github.com/WordPress/gutenberg/issues/82124)).

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.

THe changelog should link to this PR

Suggested change
- `Dropdown`: Close popover when focus moves to an unrelated dialog outside the dropdown ([#82124](https://github.com/WordPress/gutenberg/issues/82124)).
- `Dropdown`: Close popover when focus moves to an unrelated dialog outside the dropdown ([#82170](https://github.com/WordPress/gutenberg/issues/82170)).

@t-hamano t-hamano added [Type] Bug An existing feature does not function as intended Browser Issues Issues or PRs that are related to browser specific problems labels Aug 29, 2026
@ciampo

ciampo commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

@wprashed let me know if you're still able to work on this PR, otherwise I'll take over.

@ciampo

ciampo commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Closing for inactivity. Will continue in #82284 and credit @wprashed as a co-author.

@wprashed

wprashed commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Continued in #82371 with all review feedback addressed (capture event handlers, keyboard Tab support, complete test suite in index.jsdom.test.tsx, and changelog entry).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Browser Issues Issues or PRs that are related to browser specific problems [Package] Components /packages/components [Type] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom HTML: Transform popover stays open when opening "Edit code" from the block toolbar

3 participants