[Flyout System] Add main flyout to child focus trap#9397
[Flyout System] Add main flyout to child focus trap#9397angeles-mb merged 6 commits intoelastic:mainfrom
Conversation
a7d8c6b to
71d6d6b
Compare
weronikaolejniczak
left a comment
There was a problem hiding this comment.
🟢 I tested in EUI Storybook and confirmed this is working as expected:
| Before (prod) | After |
|---|---|
Kapture.2026-02-18.at.16.56.59.mp4 |
Kapture.2026-02-18.at.16.55.50.mp4 |
❌ But I also tested in Kibana. I validated it doesn't work before but it seems after using the EUI version from this PR the issue is not solved:
Before:
Kapture.2026-02-18.at.16.38.49.mp4
After:
Kapture.2026-02-18.at.16.49.19.mp4
My testing steps:
# in Kibana
yarn es
yarn start --run-examples
# validated it you cannot move with the keyboard from child to the parent flyout
# in EUI
gh pr checkout 9397
yarn workspace @elastic/eui build-pack
mv package.tgz ../kibana
# in Kibana
# updated in `package.json` to `@elastic/eui: "file:./package.tgz"`
yarn kbn bootstrap --no-validateAFAIK this should work and we don't need to make any additional changes on Kibana side, right?
Additionally, it's not a blocking suggestion but the test could be even better if we validated the expected keyboard behavior 😄
|
I tested this on Kibana's side and this is what I'm seeing:
Would that be "acceptable" from an a11y point of view @weronikaolejniczak ? Screen.Recording.2026-02-18.at.17.32.23.mov |
71d6d6b to
fe33f3f
Compare
fe33f3f to
94879e2
Compare
| // Include parent in focus trap shards for side-by-side mode (unified navigation). | ||
| // In stacked mode, parent is hidden behind child so shouldn't be navigable. | ||
| if (isSideBySideChild) { | ||
| selectors.push(`[${PROPERTY_LEVEL}="${LEVEL_MAIN}"]`); | ||
| } |
There was a problem hiding this comment.
question:
Logically, if the contrary is the truth (!isSideBySideChild), we should remove that selector from focus trap selectors?
There was a problem hiding this comment.
I don't think that is necessary since the main flyout selector is only added conditionally and recalculated on every render. At first I had it added for every child flyout. Then I realized that if I did that, we would be able to navigate between child and parent flyouts which were stacked (we would confusingly navigate to a parent flyout which was not visible).
weronikaolejniczak
left a comment
There was a problem hiding this comment.
This time I was only testing in Kibana with EUI built from this PR.
Everything works as I would expect it to. We can navigate between the child and main flyout (and other global page landmarks), all expected announcements are made, ARIA attributes are applied as per @alexwizp's concern.
From me it's 🟢 Thank you for your patience, for digging deeper and coming with a perfectly balanced solution, Angeles!
I'm not sure why JAWS doesn't announce everything as expected so I'd double-check the result with @alexwizp or @bhavyarm. But for me because NVDA and VO are working, I can tab through the flyouts and ARIA are applied correctly, it's okay.
✅ ARIA attributes
Side-by-side:
The main flyout has role="dialog" and aria-modal.
Stacked:
The child flyout has role="dialog" and aria-modal.
✅ Safari + VO
Kapture.2026-03-02.at.11.30.30.mp4
(Turn on sound 🔊)
✅ Edge + NVDA (Windows in Parallels VM)
Kapture.2026-03-02.at.11.57.17.mp4
(Turn on sound, be careful cause it's distorted 🔊)
⚠️ Edge + JAWS (Windows in Parallels VM)
Kapture.2026-03-02.at.12.04.38.mp4
Some announcements are missing in Firefox for the child flyout.
(Turn on sound, be careful cause it's distorted 🔊)
⚠️ Firefox + JAWS (Windows in Parallels VM)
Kapture.2026-03-02.at.12.01.34.mp4
Some announcements are missing in Firefox for the child flyout.
(Turn on sound, be careful cause it's distorted 🔊)
|
Thanks for the review and such thorough testing @weronikaolejniczak 🙌 |
|
@weronikaolejniczak Thanks so much for such thorough testing. Making a note about jaws. |
💚 Build SucceededHistory
cc @angeles-mb |
💚 Build Succeeded
History
cc @angeles-mb |
Summary
This PR:
aria-modalattribute to main flyout to avoid having inside one focus trap 2 elements witharia-modalWhy are we making this change?
Closes #9334
Mouse users can interact with the parent flyout while the child flyout is open. Before this change, keyboard users could only navigate inside the child flyout or close it. With this change, keyboard users will be able to achieve the same navigation as mouse users by navigating between flyouts.
You can read more about how we use Flyouts in Kibana to better understand why we are making this change here.
Screenshots #
Relevant use cases to test in Flyout Manager stories:
VMWareFusion + Chrome + NVDA:
Screen.Recording.2026-02-27.at.11.41.01.mov
Screen.Recording.2026-02-27.at.11.33.57.mov
Kibana Chrome + VO:
Screen.Recording.2026-02-27.at.12.14.54.mov
Screen.Recording.2026-02-27.at.12.24.25.mov
If you want to test on Kibana:
yarn start --run-examplesIf testing in Safari, notice that you will encounter keyboard navigation issues related to this a11y issue we currently have open: Skip to main content not working when there is opened flyout
Impact to users
A11y enhancement.
QA
Remove or strikethrough items that do not apply to your PR.
General checklist
Checked in both light and dark modesChecked in both MacOS and Windows high contrast modesChecked in mobileProps have proper autodocs (using@defaultif default values are missing) and playground togglesChecked Code Sandbox works for any docs examplesUpdated visual regression testsIf applicable, added the breaking change issue label (and filled out the breaking change checklist)If the changes unblock an issue in a different repo, smoke tested carefully (see Testing EUI features in Kibana ahead of time)If applicable, file an issue to update EUI's Figma library with any corresponding UI changes. (This is an internal repo, if you are external to Elastic, ask a maintainer to submit this request)