Skip to content

[SideNav] Fix popover vs flyout trap focus#238230

Merged
weronikaolejniczak merged 1 commit intoelastic:mainfrom
weronikaolejniczak:fix/popover-flyout-conflict
Oct 14, 2025
Merged

[SideNav] Fix popover vs flyout trap focus#238230
weronikaolejniczak merged 1 commit intoelastic:mainfrom
weronikaolejniczak:fix/popover-flyout-conflict

Conversation

@weronikaolejniczak
Copy link
Copy Markdown
Contributor

@weronikaolejniczak weronikaolejniczak commented Oct 9, 2025

Summary

Currently, there is an issue with the popover interactiveness when there's a flyout with a focus trap on the screen.

Kapture.2025-10-06.at.17.44.03.mp4

The changes on this PR patch this behavior in the side nav by only calling the blur callback if the focus is not trapped by the flyout.

Warning

This is not a long-term solution. It's a quick and dirty fix so that things work but it gives us more time to fix the issue meaningfully without affecting the users.

Details

EuiFlyout wraps its contents in an internal focus trap.

The moment you click into the popover, that trap yanks focus back into the flyout. Because handleBlur runs on the wrapper div, it sees the blur event, notices that relatedTarget is no longer inside the trigger or the popover, and immediately calls handleClose. From the user perspective the popover isn't interactive because any click sends focus to the flyout -> the blur handler fires -> the popover closes.

When we remove handleBlur, we stop clearing anyPopoverOpen on blur. That global flag then stays true and so the delayed handleMouseEnter / tryOpen logic bails out (tryOpen won’t reopen while it thinks another popover is active; it's purpose is to avoid toggling several popovers at once when navigating with a keyboard). As a result the popover never appears when you focus the trigger via keyboard.

So with handleBlur present the focus trap keeps closing the popover. Without it the open state never resets, blocking keyboard-triggered opens.

euiIncludeSelectorInFocusTrap doesn't work (specifically panelProps={euiIncludeSelectorInFocusTrap.prop} on EuiPopover). It looks like the focus trap captures matched elements only when the flyout opens but the popover panel is added later via a portal so it’s missed.

Making the popover be inserted right next to the trigger and not portalled makes the popover a) not visible at all in the fixed layout, b) not position correctly in the grid layout.

QA

After the changes were applied:

Kapture.2025-10-09.at.13.21.47.mp4

Checklist

  • Verify that the keyboard navigation works as expected
    • I can navigate with tab and arrow keys
    • The popover opens on trigger focus
    • I can press "Enter" to move focus to the popover (these do not work in this case)
    • I can press "Escape" to move focus back to the trigger (these do not work in this case)
  • Verify that on a page with a flyout (e.g. Discover > Open session - folder icon) mouse clicks work as expected
    • I can hover over a trigger and the popover shows
    • I can click on an item in the popover and it's triggered
    • I can click on an item with submenu in "More" menu and open the nested panel

@weronikaolejniczak weronikaolejniczak self-assigned this Oct 9, 2025
@weronikaolejniczak weronikaolejniczak requested a review from a team as a code owner October 9, 2025 11:47
@weronikaolejniczak weronikaolejniczak added backport:version Backport to applied version labels v9.2.0 release_note:skip Skip the PR/issue when compiling release notes labels Oct 9, 2025
@weronikaolejniczak
Copy link
Copy Markdown
Contributor Author

@Dosant did you test it? 🙏🏻

@Dosant
Copy link
Copy Markdown
Contributor

Dosant commented Oct 9, 2025

I tested now, and can confirm it fixes the issue

@weronikaolejniczak weronikaolejniczak enabled auto-merge (squash) October 9, 2025 13:51
@kibanamachine
Copy link
Copy Markdown
Contributor

Flaky Test Runner Stats

🟠 Some tests failed. - kibana-flaky-test-suite-runner#9471

[❌] x-pack/solutions/observability/test/functional_solution_sidenav/config.ts: 9/10 tests passed.
[❌] x-pack/solutions/search/test/functional_solution_sidenav/config.ts: 9/10 tests passed.
[❌] x-pack/solutions/security/test/functional_solution_sidenav/config.ts: 5/10 tests passed.

see run history

@Dosant Dosant self-requested a review October 9, 2025 16:11
@Dosant Dosant disabled auto-merge October 10, 2025 10:04
@Dosant
Copy link
Copy Markdown
Contributor

Dosant commented Oct 10, 2025

As we talked about, there are some issues that I couldn't reproduce on my end.
Adding bunch of logs here and running ci As we talked about, there are some issues that I couldn't reproduce on my end.
#238412

@Dosant
Copy link
Copy Markdown
Contributor

Dosant commented Oct 10, 2025

The problem is that "applications" menu stays open after we've used "more" menu:

image

Looking at logs https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/9481#0199cda0-5c94-4fdc-8feb-fcdb5741e2bc

Seems like application popover was opened because of mouseenter

[00:00:25] │ debg browser[INFO] http://localhost:5620/ceecdef68035/bundles/core/core.entry.js 0:65827 "*** [Popover:Applications] handleMouseEnter() - persistent=false, isOpenedByClick=false"
[00:00:25] │ debg browser[INFO] http://localhost:5620/ceecdef68035/bundles/core/core.entry.js 0:65827 "*** [Popover:Applications] handleMouseEnter() - no popover open,
00:25] │ debg browser[INFO] http://localhost:5620/ceecdef68035/bundles/core/core.entry.js 0:65827 "*** [Popover:Applications] open() - setting isOpen=true, anyPopoverOpen= false"
[00:00:25] │ debg browser[INFO] http://localhost:5620/ceecdef68035/bundles/core/core.entry.js 0:65827 "*** [Popover:Applications] open() - isSidePanelOpen=false, previous anyPopoverOpen=false"

I don't know ... couldn't be that the test randomly leaves cursor on that application menu item? if so, why we didn't see the issue before? No idea...

@Dosant
Copy link
Copy Markdown
Contributor

Dosant commented Oct 10, 2025

I don't know if there is a real problem. Maybe there is with the new re-renderings, not sure.

This alternative fix seems like it doesn't have this flakiness #238492

I also tried this simpler fix, but it still has the flakiness in it: #238589 (comment)

@weronikaolejniczak weronikaolejniczak force-pushed the fix/popover-flyout-conflict branch from db931dc to d33e053 Compare October 14, 2025 08:54
@weronikaolejniczak weronikaolejniczak changed the title [SideNav] Apply blur only when keyboard navigating [SideNav] Fix popover vs flyout trap focus Oct 14, 2025
@weronikaolejniczak weronikaolejniczak force-pushed the fix/popover-flyout-conflict branch 3 times, most recently from 2169c02 to 47fa903 Compare October 14, 2025 10:16
@weronikaolejniczak
Copy link
Copy Markdown
Contributor Author

weronikaolejniczak commented Oct 14, 2025

Calling handleBlur conditionally:

Kapture.2025-10-14.at.11.39.17.mp4

Omitting close when flyout traps the focus:

Kapture.2025-10-14.at.11.34.31.mp4

Both work as expected. The second seems to not cause flakiness in CI.


Long-term solution would be making EuiFlyout listen to DOM changes, and updating the shards to include in the focus trap. We're moving on with the quick fix to make it for Oct 23. If we manage to fix EUI before that date - perfect!

EDIT: Task on EUI side elastic/eui#9099

@weronikaolejniczak weronikaolejniczak enabled auto-merge (squash) October 14, 2025 11:34
@weronikaolejniczak weronikaolejniczak force-pushed the fix/popover-flyout-conflict branch from 47fa903 to f575a44 Compare October 14, 2025 11:34
@weronikaolejniczak weronikaolejniczak enabled auto-merge (squash) October 14, 2025 13:26
@weronikaolejniczak weronikaolejniczak merged commit 9ab2151 into elastic:main Oct 14, 2025
12 checks passed
@kibanamachine
Copy link
Copy Markdown
Contributor

Starting backport for target branches: 9.2

https://github.com/elastic/kibana/actions/runs/18500282477

@elasticmachine
Copy link
Copy Markdown
Contributor

💚 Build Succeeded

Metrics [docs]

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
core 132.7KB 132.8KB +58.0B

History

cc @weronikaolejniczak

kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Oct 14, 2025
## Summary

Currently, there is an issue with the popover interactiveness when
there's a flyout with a focus trap on the screen.

https://github.com/user-attachments/assets/9a94d3da-d468-43df-b16e-bb544f318e9c

The changes on this PR patch this behavior in the side nav by only
calling the blur callback if the focus is not trapped by the flyout.

> [!WARNING]
> This is not a **long-term** solution. It's a quick and dirty fix so
that things work but it gives us more time to fix the issue meaningfully
without affecting the users.

## Details

`EuiFlyout` wraps its contents in an [internal focus
trap](https://github.com/elastic/eui/blob/ed0c2c0b73239c06766eca1225101032d2a6287b/packages/eui/src/components/flyout/flyout.tsx#L529-L552).

The moment you click into the popover, that trap yanks focus back into
the flyout. Because `handleBlur` runs on the wrapper div, it sees the
blur event, notices that `relatedTarget` is no longer inside the trigger
or the popover, and immediately calls `handleClose`. From the
user perspective the popover isn't interactive because any click
sends focus to the flyout -> the blur handler fires -> the popover
closes.

When we remove `handleBlur`, we stop clearing `anyPopoverOpen` on blur.
That global flag then stays `true` and so the delayed `handleMouseEnter`
/ `tryOpen` logic bails out (`tryOpen` won’t reopen while
it thinks another popover is active; it's purpose is to avoid toggling
several popovers at once when navigating with a keyboard). As a result
the popover never appears when you focus the trigger via keyboard.

So with `handleBlur` present the focus trap keeps closing the popover.
Without it the open state never resets, blocking keyboard-triggered
opens.

`euiIncludeSelectorInFocusTrap` doesn't work (specifically
`panelProps={euiIncludeSelectorInFocusTrap.prop}` on `EuiPopover`). It
looks like the focus trap captures matched elements only when the flyout
opens but the popover panel is added later via a portal so it’s missed.

Making the popover be inserted right next to the trigger and not
portalled makes the popover a) not visible at all in the fixed layout,
b) not position correctly in the grid layout.

## QA

After the changes were applied:

https://github.com/user-attachments/assets/769b07c3-0657-457f-87fd-8e6410ce7e4d

### Checklist

- [ ] Verify that the keyboard navigation works as expected
  - [ ] I can navigate with tab and arrow keys
  - [ ] The popover opens on trigger focus
- [ ] ~I can press "Enter" to move focus to the popover~ (these do not
work in this case)
- [ ] ~I can press "Escape" to move focus back to the trigger~ (these do
not work in this case)
- [ ] Verify that on a page with a flyout (e.g. Discover > Open session
- folder icon) mouse clicks work as expected
  - [ ] I can hover over a trigger and the popover shows
  - [ ] I can click on an item in the popover and it's triggered
- [ ] I can click on an item with submenu in "More" menu and open the
nested panel

(cherry picked from commit 9ab2151)
@kibanamachine
Copy link
Copy Markdown
Contributor

💚 All backports created successfully

Status Branch Result
9.2

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

kibanamachine added a commit that referenced this pull request Oct 14, 2025
# Backport

This will backport the following commits from `main` to `9.2`:
- [[SideNav] Fix popover vs flyout trap focus
(#238230)](#238230)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Weronika
Olejniczak","email":"32842468+weronikaolejniczak@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-10-14T14:39:57Z","message":"[SideNav]
Fix popover vs flyout trap focus (#238230)\n\n## Summary\n\nCurrently,
there is an issue with the popover interactiveness when\nthere's a
flyout with a focus trap on the
screen.\n\n\nhttps://github.com/user-attachments/assets/9a94d3da-d468-43df-b16e-bb544f318e9c\n\nThe
changes on this PR patch this behavior in the side nav by only\ncalling
the blur callback if the focus is not trapped by the flyout.\n\n>
[!WARNING]\n> This is not a **long-term** solution. It's a quick and
dirty fix so\nthat things work but it gives us more time to fix the
issue meaningfully\nwithout affecting the users.\n\n##
Details\n\n`EuiFlyout` wraps its contents in an
[internal focus\ntrap](https://github.com/elastic/eui/blob/ed0c2c0b73239c06766eca1225101032d2a6287b/packages/eui/src/components/flyout/flyout.tsx#L529-L552).\n\nThe
moment you click into the popover, that trap yanks focus back into\nthe
flyout. Because `handleBlur` runs on the wrapper div, it sees the\nblur
event, notices that `relatedTarget` is no longer inside the trigger\nor
the popover, and immediately calls `handleClose`. From
the\nuser perspective the popover isn't interactive because any
click\nsends focus to the flyout -> the blur handler fires -> the
popover\ncloses.\n\nWhen we remove `handleBlur`, we stop
clearing `anyPopoverOpen` on blur.\nThat global flag then stays `true`
and so the delayed `handleMouseEnter`\n/ `tryOpen` logic bails out
(`tryOpen` won’t reopen while\nit thinks another popover is active; it's
purpose is to avoid toggling\nseveral popovers at once when navigating
with a keyboard). As a result\nthe popover never appears when
you focus the trigger via keyboard.\n\nSo
with `handleBlur` present the focus trap keeps closing the
popover.\nWithout it the open state never resets, blocking
keyboard-triggered\nopens.\n\n`euiIncludeSelectorInFocusTrap` doesn't
work (specifically\n`panelProps={euiIncludeSelectorInFocusTrap.prop}` on
`EuiPopover`). It\nlooks like the focus trap captures matched elements
only when the flyout\nopens but the popover panel is added later via a
portal so it’s missed.\n\nMaking the popover be inserted right next to
the trigger and not\nportalled makes the popover a) not visible at all
in the fixed layout,\nb) not position correctly in the grid
layout.\n\n## QA\n\nAfter the changes were
applied:\n\n\nhttps://github.com/user-attachments/assets/769b07c3-0657-457f-87fd-8e6410ce7e4d\n\n###
Checklist\n\n- [ ] Verify that the keyboard navigation works as
expected\n - [ ] I can navigate with tab and arrow keys\n - [ ] The
popover opens on trigger focus\n- [ ] ~I can press \"Enter\" to move
focus to the popover~ (these do not\nwork in this case)\n- [ ] ~I can
press \"Escape\" to move focus back to the trigger~ (these do\nnot work
in this case)\n- [ ] Verify that on a page with a flyout (e.g. Discover
> Open session\n- folder icon) mouse clicks work as expected\n - [ ] I
can hover over a trigger and the popover shows\n - [ ] I can click on an
item in the popover and it's triggered\n- [ ] I can click on an item
with submenu in \"More\" menu and open the\nnested
panel","sha":"9ab2151ee99a3b0d60dd9c223eae25d0a1b4873f","branchLabelMapping":{"^v9.3.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport:version","v9.2.0","v9.3.0"],"title":"[SideNav]
Fix popover vs flyout trap
focus","number":238230,"url":"https://github.com/elastic/kibana/pull/238230","mergeCommit":{"message":"[SideNav]
Fix popover vs flyout trap focus (#238230)\n\n## Summary\n\nCurrently,
there is an issue with the popover interactiveness when\nthere's a
flyout with a focus trap on the
screen.\n\n\nhttps://github.com/user-attachments/assets/9a94d3da-d468-43df-b16e-bb544f318e9c\n\nThe
changes on this PR patch this behavior in the side nav by only\ncalling
the blur callback if the focus is not trapped by the flyout.\n\n>
[!WARNING]\n> This is not a **long-term** solution. It's a quick and
dirty fix so\nthat things work but it gives us more time to fix the
issue meaningfully\nwithout affecting the users.\n\n##
Details\n\n`EuiFlyout` wraps its contents in an
[internal focus\ntrap](https://github.com/elastic/eui/blob/ed0c2c0b73239c06766eca1225101032d2a6287b/packages/eui/src/components/flyout/flyout.tsx#L529-L552).\n\nThe
moment you click into the popover, that trap yanks focus back into\nthe
flyout. Because `handleBlur` runs on the wrapper div, it sees the\nblur
event, notices that `relatedTarget` is no longer inside the trigger\nor
the popover, and immediately calls `handleClose`. From
the\nuser perspective the popover isn't interactive because any
click\nsends focus to the flyout -> the blur handler fires -> the
popover\ncloses.\n\nWhen we remove `handleBlur`, we stop
clearing `anyPopoverOpen` on blur.\nThat global flag then stays `true`
and so the delayed `handleMouseEnter`\n/ `tryOpen` logic bails out
(`tryOpen` won’t reopen while\nit thinks another popover is active; it's
purpose is to avoid toggling\nseveral popovers at once when navigating
with a keyboard). As a result\nthe popover never appears when
you focus the trigger via keyboard.\n\nSo
with `handleBlur` present the focus trap keeps closing the
popover.\nWithout it the open state never resets, blocking
keyboard-triggered\nopens.\n\n`euiIncludeSelectorInFocusTrap` doesn't
work (specifically\n`panelProps={euiIncludeSelectorInFocusTrap.prop}` on
`EuiPopover`). It\nlooks like the focus trap captures matched elements
only when the flyout\nopens but the popover panel is added later via a
portal so it’s missed.\n\nMaking the popover be inserted right next to
the trigger and not\nportalled makes the popover a) not visible at all
in the fixed layout,\nb) not position correctly in the grid
layout.\n\n## QA\n\nAfter the changes were
applied:\n\n\nhttps://github.com/user-attachments/assets/769b07c3-0657-457f-87fd-8e6410ce7e4d\n\n###
Checklist\n\n- [ ] Verify that the keyboard navigation works as
expected\n - [ ] I can navigate with tab and arrow keys\n - [ ] The
popover opens on trigger focus\n- [ ] ~I can press \"Enter\" to move
focus to the popover~ (these do not\nwork in this case)\n- [ ] ~I can
press \"Escape\" to move focus back to the trigger~ (these do\nnot work
in this case)\n- [ ] Verify that on a page with a flyout (e.g. Discover
> Open session\n- folder icon) mouse clicks work as expected\n - [ ] I
can hover over a trigger and the popover shows\n - [ ] I can click on an
item in the popover and it's triggered\n- [ ] I can click on an item
with submenu in \"More\" menu and open the\nnested
panel","sha":"9ab2151ee99a3b0d60dd9c223eae25d0a1b4873f"}},"sourceBranch":"main","suggestedTargetBranches":["9.2"],"targetPullRequestStates":[{"branch":"9.2","label":"v9.2.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.3.0","branchLabelMappingKey":"^v9.3.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/238230","number":238230,"mergeCommit":{"message":"[SideNav]
Fix popover vs flyout trap focus (#238230)\n\n## Summary\n\nCurrently,
there is an issue with the popover interactiveness when\nthere's a
flyout with a focus trap on the
screen.\n\n\nhttps://github.com/user-attachments/assets/9a94d3da-d468-43df-b16e-bb544f318e9c\n\nThe
changes on this PR patch this behavior in the side nav by only\ncalling
the blur callback if the focus is not trapped by the flyout.\n\n>
[!WARNING]\n> This is not a **long-term** solution. It's a quick and
dirty fix so\nthat things work but it gives us more time to fix the
issue meaningfully\nwithout affecting the users.\n\n##
Details\n\n`EuiFlyout` wraps its contents in an
[internal focus\ntrap](https://github.com/elastic/eui/blob/ed0c2c0b73239c06766eca1225101032d2a6287b/packages/eui/src/components/flyout/flyout.tsx#L529-L552).\n\nThe
moment you click into the popover, that trap yanks focus back into\nthe
flyout. Because `handleBlur` runs on the wrapper div, it sees the\nblur
event, notices that `relatedTarget` is no longer inside the trigger\nor
the popover, and immediately calls `handleClose`. From
the\nuser perspective the popover isn't interactive because any
click\nsends focus to the flyout -> the blur handler fires -> the
popover\ncloses.\n\nWhen we remove `handleBlur`, we stop
clearing `anyPopoverOpen` on blur.\nThat global flag then stays `true`
and so the delayed `handleMouseEnter`\n/ `tryOpen` logic bails out
(`tryOpen` won’t reopen while\nit thinks another popover is active; it's
purpose is to avoid toggling\nseveral popovers at once when navigating
with a keyboard). As a result\nthe popover never appears when
you focus the trigger via keyboard.\n\nSo
with `handleBlur` present the focus trap keeps closing the
popover.\nWithout it the open state never resets, blocking
keyboard-triggered\nopens.\n\n`euiIncludeSelectorInFocusTrap` doesn't
work (specifically\n`panelProps={euiIncludeSelectorInFocusTrap.prop}` on
`EuiPopover`). It\nlooks like the focus trap captures matched elements
only when the flyout\nopens but the popover panel is added later via a
portal so it’s missed.\n\nMaking the popover be inserted right next to
the trigger and not\nportalled makes the popover a) not visible at all
in the fixed layout,\nb) not position correctly in the grid
layout.\n\n## QA\n\nAfter the changes were
applied:\n\n\nhttps://github.com/user-attachments/assets/769b07c3-0657-457f-87fd-8e6410ce7e4d\n\n###
Checklist\n\n- [ ] Verify that the keyboard navigation works as
expected\n - [ ] I can navigate with tab and arrow keys\n - [ ] The
popover opens on trigger focus\n- [ ] ~I can press \"Enter\" to move
focus to the popover~ (these do not\nwork in this case)\n- [ ] ~I can
press \"Escape\" to move focus back to the trigger~ (these do\nnot work
in this case)\n- [ ] Verify that on a page with a flyout (e.g. Discover
> Open session\n- folder icon) mouse clicks work as expected\n - [ ] I
can hover over a trigger and the popover shows\n - [ ] I can click on an
item in the popover and it's triggered\n- [ ] I can click on an item
with submenu in \"More\" menu and open the\nnested
panel","sha":"9ab2151ee99a3b0d60dd9c223eae25d0a1b4873f"}}]}] BACKPORT-->

Co-authored-by: Weronika Olejniczak <32842468+weronikaolejniczak@users.noreply.github.com>
ersin-erdal pushed a commit to ersin-erdal/kibana that referenced this pull request Oct 15, 2025
## Summary

Currently, there is an issue with the popover interactiveness when
there's a flyout with a focus trap on the screen.


https://github.com/user-attachments/assets/9a94d3da-d468-43df-b16e-bb544f318e9c

The changes on this PR patch this behavior in the side nav by only
calling the blur callback if the focus is not trapped by the flyout.

> [!WARNING]
> This is not a **long-term** solution. It's a quick and dirty fix so
that things work but it gives us more time to fix the issue meaningfully
without affecting the users.

## Details

`EuiFlyout` wraps its contents in an [internal focus
trap](https://github.com/elastic/eui/blob/ed0c2c0b73239c06766eca1225101032d2a6287b/packages/eui/src/components/flyout/flyout.tsx#L529-L552).

The moment you click into the popover, that trap yanks focus back into
the flyout. Because `handleBlur` runs on the wrapper div, it sees the
blur event, notices that `relatedTarget` is no longer inside the trigger
or the popover, and immediately calls `handleClose`. From the
user perspective the popover isn't interactive because any click
sends focus to the flyout -> the blur handler fires -> the popover
closes.

When we remove `handleBlur`, we stop clearing `anyPopoverOpen` on blur.
That global flag then stays `true` and so the delayed `handleMouseEnter`
/ `tryOpen` logic bails out (`tryOpen` won’t reopen while
it thinks another popover is active; it's purpose is to avoid toggling
several popovers at once when navigating with a keyboard). As a result
the popover never appears when you focus the trigger via keyboard.

So with `handleBlur` present the focus trap keeps closing the popover.
Without it the open state never resets, blocking keyboard-triggered
opens.

`euiIncludeSelectorInFocusTrap` doesn't work (specifically
`panelProps={euiIncludeSelectorInFocusTrap.prop}` on `EuiPopover`). It
looks like the focus trap captures matched elements only when the flyout
opens but the popover panel is added later via a portal so it’s missed.

Making the popover be inserted right next to the trigger and not
portalled makes the popover a) not visible at all in the fixed layout,
b) not position correctly in the grid layout.

## QA

After the changes were applied:


https://github.com/user-attachments/assets/769b07c3-0657-457f-87fd-8e6410ce7e4d

### Checklist

- [ ] Verify that the keyboard navigation works as expected
  - [ ] I can navigate with tab and arrow keys
  - [ ] The popover opens on trigger focus
- [ ] ~I can press "Enter" to move focus to the popover~ (these do not
work in this case)
- [ ] ~I can press "Escape" to move focus back to the trigger~ (these do
not work in this case)
- [ ] Verify that on a page with a flyout (e.g. Discover > Open session
- folder icon) mouse clicks work as expected
  - [ ] I can hover over a trigger and the popover shows
  - [ ] I can click on an item in the popover and it's triggered
- [ ] I can click on an item with submenu in "More" menu and open the
nested panel
mgadewoll pushed a commit to tkajtoch/kibana that referenced this pull request Oct 17, 2025
## Summary

Currently, there is an issue with the popover interactiveness when
there's a flyout with a focus trap on the screen.


https://github.com/user-attachments/assets/9a94d3da-d468-43df-b16e-bb544f318e9c

The changes on this PR patch this behavior in the side nav by only
calling the blur callback if the focus is not trapped by the flyout.

> [!WARNING]
> This is not a **long-term** solution. It's a quick and dirty fix so
that things work but it gives us more time to fix the issue meaningfully
without affecting the users.

## Details

`EuiFlyout` wraps its contents in an [internal focus
trap](https://github.com/elastic/eui/blob/ed0c2c0b73239c06766eca1225101032d2a6287b/packages/eui/src/components/flyout/flyout.tsx#L529-L552).

The moment you click into the popover, that trap yanks focus back into
the flyout. Because `handleBlur` runs on the wrapper div, it sees the
blur event, notices that `relatedTarget` is no longer inside the trigger
or the popover, and immediately calls `handleClose`. From the
user perspective the popover isn't interactive because any click
sends focus to the flyout -> the blur handler fires -> the popover
closes.

When we remove `handleBlur`, we stop clearing `anyPopoverOpen` on blur.
That global flag then stays `true` and so the delayed `handleMouseEnter`
/ `tryOpen` logic bails out (`tryOpen` won’t reopen while
it thinks another popover is active; it's purpose is to avoid toggling
several popovers at once when navigating with a keyboard). As a result
the popover never appears when you focus the trigger via keyboard.

So with `handleBlur` present the focus trap keeps closing the popover.
Without it the open state never resets, blocking keyboard-triggered
opens.

`euiIncludeSelectorInFocusTrap` doesn't work (specifically
`panelProps={euiIncludeSelectorInFocusTrap.prop}` on `EuiPopover`). It
looks like the focus trap captures matched elements only when the flyout
opens but the popover panel is added later via a portal so it’s missed.

Making the popover be inserted right next to the trigger and not
portalled makes the popover a) not visible at all in the fixed layout,
b) not position correctly in the grid layout.

## QA

After the changes were applied:


https://github.com/user-attachments/assets/769b07c3-0657-457f-87fd-8e6410ce7e4d

### Checklist

- [ ] Verify that the keyboard navigation works as expected
  - [ ] I can navigate with tab and arrow keys
  - [ ] The popover opens on trigger focus
- [ ] ~I can press "Enter" to move focus to the popover~ (these do not
work in this case)
- [ ] ~I can press "Escape" to move focus back to the trigger~ (these do
not work in this case)
- [ ] Verify that on a page with a flyout (e.g. Discover > Open session
- folder icon) mouse clicks work as expected
  - [ ] I can hover over a trigger and the popover shows
  - [ ] I can click on an item in the popover and it's triggered
- [ ] I can click on an item with submenu in "More" menu and open the
nested panel
rylnd pushed a commit to rylnd/kibana that referenced this pull request Oct 17, 2025
## Summary

Currently, there is an issue with the popover interactiveness when
there's a flyout with a focus trap on the screen.


https://github.com/user-attachments/assets/9a94d3da-d468-43df-b16e-bb544f318e9c

The changes on this PR patch this behavior in the side nav by only
calling the blur callback if the focus is not trapped by the flyout.

> [!WARNING]
> This is not a **long-term** solution. It's a quick and dirty fix so
that things work but it gives us more time to fix the issue meaningfully
without affecting the users.

## Details

`EuiFlyout` wraps its contents in an [internal focus
trap](https://github.com/elastic/eui/blob/ed0c2c0b73239c06766eca1225101032d2a6287b/packages/eui/src/components/flyout/flyout.tsx#L529-L552).

The moment you click into the popover, that trap yanks focus back into
the flyout. Because `handleBlur` runs on the wrapper div, it sees the
blur event, notices that `relatedTarget` is no longer inside the trigger
or the popover, and immediately calls `handleClose`. From the
user perspective the popover isn't interactive because any click
sends focus to the flyout -> the blur handler fires -> the popover
closes.

When we remove `handleBlur`, we stop clearing `anyPopoverOpen` on blur.
That global flag then stays `true` and so the delayed `handleMouseEnter`
/ `tryOpen` logic bails out (`tryOpen` won’t reopen while
it thinks another popover is active; it's purpose is to avoid toggling
several popovers at once when navigating with a keyboard). As a result
the popover never appears when you focus the trigger via keyboard.

So with `handleBlur` present the focus trap keeps closing the popover.
Without it the open state never resets, blocking keyboard-triggered
opens.

`euiIncludeSelectorInFocusTrap` doesn't work (specifically
`panelProps={euiIncludeSelectorInFocusTrap.prop}` on `EuiPopover`). It
looks like the focus trap captures matched elements only when the flyout
opens but the popover panel is added later via a portal so it’s missed.

Making the popover be inserted right next to the trigger and not
portalled makes the popover a) not visible at all in the fixed layout,
b) not position correctly in the grid layout.

## QA

After the changes were applied:


https://github.com/user-attachments/assets/769b07c3-0657-457f-87fd-8e6410ce7e4d

### Checklist

- [ ] Verify that the keyboard navigation works as expected
  - [ ] I can navigate with tab and arrow keys
  - [ ] The popover opens on trigger focus
- [ ] ~I can press "Enter" to move focus to the popover~ (these do not
work in this case)
- [ ] ~I can press "Escape" to move focus back to the trigger~ (these do
not work in this case)
- [ ] Verify that on a page with a flyout (e.g. Discover > Open session
- folder icon) mouse clicks work as expected
  - [ ] I can hover over a trigger and the popover shows
  - [ ] I can click on an item in the popover and it's triggered
- [ ] I can click on an item with submenu in "More" menu and open the
nested panel
nickpeihl pushed a commit to nickpeihl/kibana that referenced this pull request Oct 23, 2025
## Summary

Currently, there is an issue with the popover interactiveness when
there's a flyout with a focus trap on the screen.


https://github.com/user-attachments/assets/9a94d3da-d468-43df-b16e-bb544f318e9c

The changes on this PR patch this behavior in the side nav by only
calling the blur callback if the focus is not trapped by the flyout.

> [!WARNING]
> This is not a **long-term** solution. It's a quick and dirty fix so
that things work but it gives us more time to fix the issue meaningfully
without affecting the users.

## Details

`EuiFlyout` wraps its contents in an [internal focus
trap](https://github.com/elastic/eui/blob/ed0c2c0b73239c06766eca1225101032d2a6287b/packages/eui/src/components/flyout/flyout.tsx#L529-L552).

The moment you click into the popover, that trap yanks focus back into
the flyout. Because `handleBlur` runs on the wrapper div, it sees the
blur event, notices that `relatedTarget` is no longer inside the trigger
or the popover, and immediately calls `handleClose`. From the
user perspective the popover isn't interactive because any click
sends focus to the flyout -> the blur handler fires -> the popover
closes.

When we remove `handleBlur`, we stop clearing `anyPopoverOpen` on blur.
That global flag then stays `true` and so the delayed `handleMouseEnter`
/ `tryOpen` logic bails out (`tryOpen` won’t reopen while
it thinks another popover is active; it's purpose is to avoid toggling
several popovers at once when navigating with a keyboard). As a result
the popover never appears when you focus the trigger via keyboard.

So with `handleBlur` present the focus trap keeps closing the popover.
Without it the open state never resets, blocking keyboard-triggered
opens.

`euiIncludeSelectorInFocusTrap` doesn't work (specifically
`panelProps={euiIncludeSelectorInFocusTrap.prop}` on `EuiPopover`). It
looks like the focus trap captures matched elements only when the flyout
opens but the popover panel is added later via a portal so it’s missed.

Making the popover be inserted right next to the trigger and not
portalled makes the popover a) not visible at all in the fixed layout,
b) not position correctly in the grid layout.

## QA

After the changes were applied:


https://github.com/user-attachments/assets/769b07c3-0657-457f-87fd-8e6410ce7e4d

### Checklist

- [ ] Verify that the keyboard navigation works as expected
  - [ ] I can navigate with tab and arrow keys
  - [ ] The popover opens on trigger focus
- [ ] ~I can press "Enter" to move focus to the popover~ (these do not
work in this case)
- [ ] ~I can press "Escape" to move focus back to the trigger~ (these do
not work in this case)
- [ ] Verify that on a page with a flyout (e.g. Discover > Open session
- folder icon) mouse clicks work as expected
  - [ ] I can hover over a trigger and the popover shows
  - [ ] I can click on an item in the popover and it's triggered
- [ ] I can click on an item with submenu in "More" menu and open the
nested panel
NicholasPeretti pushed a commit to NicholasPeretti/kibana that referenced this pull request Oct 27, 2025
## Summary

Currently, there is an issue with the popover interactiveness when
there's a flyout with a focus trap on the screen.


https://github.com/user-attachments/assets/9a94d3da-d468-43df-b16e-bb544f318e9c

The changes on this PR patch this behavior in the side nav by only
calling the blur callback if the focus is not trapped by the flyout.

> [!WARNING]
> This is not a **long-term** solution. It's a quick and dirty fix so
that things work but it gives us more time to fix the issue meaningfully
without affecting the users.

## Details

`EuiFlyout` wraps its contents in an [internal focus
trap](https://github.com/elastic/eui/blob/ed0c2c0b73239c06766eca1225101032d2a6287b/packages/eui/src/components/flyout/flyout.tsx#L529-L552).

The moment you click into the popover, that trap yanks focus back into
the flyout. Because `handleBlur` runs on the wrapper div, it sees the
blur event, notices that `relatedTarget` is no longer inside the trigger
or the popover, and immediately calls `handleClose`. From the
user perspective the popover isn't interactive because any click
sends focus to the flyout -> the blur handler fires -> the popover
closes.

When we remove `handleBlur`, we stop clearing `anyPopoverOpen` on blur.
That global flag then stays `true` and so the delayed `handleMouseEnter`
/ `tryOpen` logic bails out (`tryOpen` won’t reopen while
it thinks another popover is active; it's purpose is to avoid toggling
several popovers at once when navigating with a keyboard). As a result
the popover never appears when you focus the trigger via keyboard.

So with `handleBlur` present the focus trap keeps closing the popover.
Without it the open state never resets, blocking keyboard-triggered
opens.

`euiIncludeSelectorInFocusTrap` doesn't work (specifically
`panelProps={euiIncludeSelectorInFocusTrap.prop}` on `EuiPopover`). It
looks like the focus trap captures matched elements only when the flyout
opens but the popover panel is added later via a portal so it’s missed.

Making the popover be inserted right next to the trigger and not
portalled makes the popover a) not visible at all in the fixed layout,
b) not position correctly in the grid layout.

## QA

After the changes were applied:


https://github.com/user-attachments/assets/769b07c3-0657-457f-87fd-8e6410ce7e4d

### Checklist

- [ ] Verify that the keyboard navigation works as expected
  - [ ] I can navigate with tab and arrow keys
  - [ ] The popover opens on trigger focus
- [ ] ~I can press "Enter" to move focus to the popover~ (these do not
work in this case)
- [ ] ~I can press "Escape" to move focus back to the trigger~ (these do
not work in this case)
- [ ] Verify that on a page with a flyout (e.g. Discover > Open session
- folder icon) mouse clicks work as expected
  - [ ] I can hover over a trigger and the popover shows
  - [ ] I can click on an item in the popover and it's triggered
- [ ] I can click on an item with submenu in "More" menu and open the
nested panel
@Dosant Dosant mentioned this pull request Nov 20, 2025
55 tasks
weronikaolejniczak added a commit that referenced this pull request Nov 21, 2025
## Summary

### Flyout

See #239500 for details.

I'm adding a proper selector to the popover panel so that it's included
in flyout focus trap shards and can be navigable with a keyboard when a
flyout is rendered.

Removed the flyout check workaround in `handleBlur` added on
#238230.


https://github.com/user-attachments/assets/3f01d80a-94f9-44be-8814-c35801906bd7

Entering a popover with a keyboard and clicking on a popover item with a
mouse both work as expected normally and when a flyout is rendered on
the screen.

### Console overlay

Resolves elastic/security-team#14810

To fix it on EUI side for flyouts, we opted for a singleton that works
with one EUI instance.

Because Security overlay
(`x-pack/solutions/security/plugins/security_solution/public/management/components/page_overlay/page_overlay.tsx`)
uses `EuiFocusTrap` directly, and adding a global Kibana singleton seems
like an overkill, I went for a Proxy array method. It's slightly more
reactive but keeps the change scoped to `PageOverlay` in Security
solution. Whenever the underlying library `react-focus-on` accesses
`shards` value, we query the elements by
`euiIncludeSelectorInFocusTrap.selector` (that on the same PR is applied
to the popovers ☝🏻).

#### Before


https://github.com/user-attachments/assets/a609598a-ddc0-425c-8590-dc3f6507b18b

#### After


https://github.com/user-attachments/assets/5bd2c783-e6bf-483d-8489-aff5b884f509

## QA

### Flyouts

Any flyout in Kibana will do. Exemplary steps to reproduce:

1. Access any solution view.
2. Go to Discover.
3. In the toolbar, to the right, click on the folder icon - "Open
session".
4. Try navigating the side nav:
- [ ] press <kbd>Enter</kbd> to move focus to the popover
- [ ] use Up and Down arrow keys to navigate the list
- [ ] press <kbd>Escape</kbd> to move focus back to the popover trigger
5. Test mouse interaction:
- [ ] hover over a menu item with a submenu to trigger the popover
- [ ] click on any menu item, it should redirect
- [ ] go back and test the nested "More" menu

### Security

Steps to reproduce are outlined in the
[issue](elastic/security-team#14810).

Run ES with: `yarn es snapshot --license trial -E
xpack.security.authc.api_key.enabled=true -E http.host=0.0.0.0`

Follow similar steps as above ☝🏻

---------

Co-authored-by: Ash <1849116+ashokaditya@users.noreply.github.com>
eokoneyo pushed a commit to eokoneyo/kibana that referenced this pull request Dec 2, 2025
## Summary

### Flyout

See elastic#239500 for details.

I'm adding a proper selector to the popover panel so that it's included
in flyout focus trap shards and can be navigable with a keyboard when a
flyout is rendered.

Removed the flyout check workaround in `handleBlur` added on
elastic#238230.


https://github.com/user-attachments/assets/3f01d80a-94f9-44be-8814-c35801906bd7

Entering a popover with a keyboard and clicking on a popover item with a
mouse both work as expected normally and when a flyout is rendered on
the screen.

### Console overlay

Resolves elastic/security-team#14810

To fix it on EUI side for flyouts, we opted for a singleton that works
with one EUI instance.

Because Security overlay
(`x-pack/solutions/security/plugins/security_solution/public/management/components/page_overlay/page_overlay.tsx`)
uses `EuiFocusTrap` directly, and adding a global Kibana singleton seems
like an overkill, I went for a Proxy array method. It's slightly more
reactive but keeps the change scoped to `PageOverlay` in Security
solution. Whenever the underlying library `react-focus-on` accesses
`shards` value, we query the elements by
`euiIncludeSelectorInFocusTrap.selector` (that on the same PR is applied
to the popovers ☝🏻).

#### Before


https://github.com/user-attachments/assets/a609598a-ddc0-425c-8590-dc3f6507b18b

#### After


https://github.com/user-attachments/assets/5bd2c783-e6bf-483d-8489-aff5b884f509

## QA

### Flyouts

Any flyout in Kibana will do. Exemplary steps to reproduce:

1. Access any solution view.
2. Go to Discover.
3. In the toolbar, to the right, click on the folder icon - "Open
session".
4. Try navigating the side nav:
- [ ] press <kbd>Enter</kbd> to move focus to the popover
- [ ] use Up and Down arrow keys to navigate the list
- [ ] press <kbd>Escape</kbd> to move focus back to the popover trigger
5. Test mouse interaction:
- [ ] hover over a menu item with a submenu to trigger the popover
- [ ] click on any menu item, it should redirect
- [ ] go back and test the nested "More" menu

### Security

Steps to reproduce are outlined in the
[issue](elastic/security-team#14810).

Run ES with: `yarn es snapshot --license trial -E
xpack.security.authc.api_key.enabled=true -E http.host=0.0.0.0`

Follow similar steps as above ☝🏻

---------

Co-authored-by: Ash <1849116+ashokaditya@users.noreply.github.com>
@weronikaolejniczak weronikaolejniczak deleted the fix/popover-flyout-conflict branch February 10, 2026 10:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:version Backport to applied version labels release_note:skip Skip the PR/issue when compiling release notes v9.2.0 v9.3.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants