Skip to content

Add FlyoutSystemMenu component #8851

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

tsullivan
Copy link
Member

@tsullivan tsullivan commented Jul 8, 2025

Closes #8873

Summary

Adds a new EuiFlyoutMenu component that provides a standardized top menu bar for flyouts. Key features:

  • Replaces the standard close button with a menu bar containing title, navigation, and close button
  • Integrates with both EuiFlyout and EuiFlyoutChild components
  • Adds support for back navigation and history through a dropdown menu

Enhances the flyout session API with:

  • New openSystemFlyout method for creating flyouts designed for flyout-to-flyout navigation (flyout sessions).
  • History filtering capability via a new historyFilter prop in EuiFlyoutSessionProvider
  • Support for titles in all flyout types (main, child, and group)
  • Improved navigation with GO_TO_HISTORY_ITEM action for direct history access

Other changes:

  • cb105a6: Fix an issue in flyoutReducer where the meta data from incoming actions needed to be merged with the past state. Caused by #8857

Why are we making this change?

Part of https://github.com/elastic/kibana-team/issues/1606 - SharedUX Flyout System

Screenshots

Demonstrating navigating deeply through history

  • The "popover" showing history allows the user to return back to a flyout screen they'd seen an arbitrary number of steps in history

menu-bar

Demonstrating the historyFilter

  • After confirming the order, the "Order Confirmation" flyout does not have a "Back" button.
  • Clicking "Close / Go Back" triggers the "Close" behavior, because history in the state can no longer be accessed.

shopping-cart-history-filter

Impact to users

QA

Remove or strikethrough items that do not apply to your PR.

General checklist

  • Browser QA
    • Checked in both light and dark modes
    • Checked in both MacOS and Windows high contrast modes
    • Checked in mobile
    • Checked in Chrome, Safari, Edge, and Firefox
    • Checked for accessibility including keyboard-only and screenreader modes
  • Docs site QA
  • Code quality checklist
  • Release checklist
    • A changelog entry exists and is marked appropriately.
    • If applicable, added the breaking change issue label (and filled out the breaking change checklist)
  • Designer checklist
    • 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)

@tsullivan tsullivan force-pushed the flyout-system/add-top-menu branch from 1538889 to 2ec3f5f Compare July 8, 2025 23:52
const newHistory = [...state.history];

if (state.activeFlyoutGroup) {
newHistory.push(state.activeFlyoutGroup);
newHistory.unshift(state.activeFlyoutGroup);
Copy link
Member Author

Choose a reason for hiding this comment

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

Changed the ordering of history items to be reversed (newest in the front) to simplify the rendering of the history popover.

@tsullivan tsullivan force-pushed the flyout-system/add-top-menu branch 2 times, most recently from a19f9d3 to 9891366 Compare July 15, 2025 00:16
@ryankeairns
Copy link
Contributor

@tsullivan I think the answer is 'yes' but will EuiFlyoutMenu be available on any EuiFlyout?
Spoiler alert: that was the expected outcome :)

@tsullivan tsullivan force-pushed the flyout-system/add-top-menu branch from 9891366 to b5a3212 Compare July 16, 2025 22:05
@tsullivan
Copy link
Member Author

tsullivan commented Jul 16, 2025

@tsullivan I think the answer is 'yes' but will EuiFlyoutMenu be available on any EuiFlyout?
Spoiler alert: that was the expected outcome :)

@ryankeairns, yes there aren't any limitations against putting an EuiFlyoutMenu in any EuiFlyout.

If you are rendering the components declaratively, you can compose them this way:

  <EuiFlyout>
    <EuiFlyoutMenu />
    <EuiFlyoutHeader />
    <EuiFlyoutBody />
    <EuiFlyoutFooter />
  </EuiFlyout>

The EuiFlyout should be smart about where to place the "close" button: it has to either go into the flyout itself or the top bar (EuiFlyoutMenu). The intention is for the EuiFlyout to check if one of the child components is an EuiFlyoutMenu, and then defer rendering the "close" button to allow it to be rendered in the EuiFlyoutMenu component.

This PR currently updates the API for state management: if you want to open a "basic" flyout and have a flyout that looks exactly the way flyouts look in the current version, then you would call openFlyout. If your use case will have flyout-to-flyout navigation flyouts and child flyouts, then you would call openSystemFlyout. The main difference is: the latter method is intended for "session" use cases and all flyouts in the session will automatically get an EuiFlyoutMenu.

Note that this PR is still in draft mode because the API decisions may need to change.

cc @clintandrewhall

@ryankeairns
Copy link
Contributor

ryankeairns commented Jul 16, 2025

Thanks @tsullivan .
For tracking purposes, I went ahead and created an issue

Added the 'Closes [issue]' text to the PR description. Feel free to remove that if you feel it is not needed here.

@tsullivan
Copy link
Member Author

Updated the description, added screenshots.

@tsullivan
Copy link
Member Author

tsullivan commented Jul 17, 2025

@ryankeairns from that issue, I see:

I want to place a common actions atop several flyotuts (e.g. back, share, settings, chat, close)

👍🏻

This PR does support custom actions that implementors want to show in the menu bar, if the developers render the flyout structure declaratively. But for developers that use state management system API:

  • openSystemFlyout openManagedFlyout: Shows menu bar automatically, with history controls, flyout title, and close button. No option for custom actions in the menu bar.
  • openFlyout: No automatic menu bar.

I think this is good for now, as I need to avoid making the state management system too polished in this phase. Some API design changes are forthcoming to meet a set of refined Kibana developer requirements. Some terminology changes will come in through that as well.

cc @clintandrewhall @ThomThomson

@ryankeairns
Copy link
Contributor

ryankeairns commented Jul 17, 2025

Understood.

For those following along, we understand that the current Security flyout does have custom actions that we'll ultimately need to support in the managed setup.

@tsullivan tsullivan force-pushed the flyout-system/add-top-menu branch from b65ce43 to 37fc2f6 Compare July 17, 2025 18:21
@tsullivan
Copy link
Member Author

Added a storybook specifically for the flyout menu, showing a custom action. For now, the layout and styling for the custom action buttons works best with when the buttons are icons, and have a customized block-size CSS.

menu-bar-demo

@tsullivan tsullivan marked this pull request as ready for review July 17, 2025 19:51
@tsullivan tsullivan requested a review from a team as a code owner July 17, 2025 19:51
@tsullivan tsullivan self-assigned this Jul 17, 2025
/**
* Title to display in top menu bar and in the options of the history popover
*/
title: string;
Copy link
Member Author

Choose a reason for hiding this comment

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

@clintandrewhall just want to point this field out specifically, because we will have to think about how titles will be displayed in the top menu bar and in the history popover with the replacement API.

Comment on lines +157 to +160
historyFilter?: (
history: EuiFlyoutSessionHistoryState<FlyoutMeta>['history'],
activeFlyoutGroup?: EuiFlyoutSessionGroup<FlyoutMeta> | null
) => EuiFlyoutSessionHistoryState<FlyoutMeta>['history'];
Copy link
Member Author

@tsullivan tsullivan Jul 22, 2025

Choose a reason for hiding this comment

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

I asked @ryankeairns about this today for clarification. When the design idea for this came up, it was to limit the number of items in the history popover visually. Old items in the history should still be accessible by scrolling down or paging back. The idea actually wasn't to give developers a way to pull items out of the history or replace a given set of history items with another, or empty the history completely. So the historyFilter mechanism as it is in this PR isn't actually needed at this point. (But maybe it doesn't hurt to leave it here).

}) => {
const { onClose } = useContext(EuiFlyoutMenuContext);

const styles = useEuiFlyoutMenuStyles();
Copy link
Member

Choose a reason for hiding this comment

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

nit: Could you please use useEuiMemoizedStyles instead? It passes euiTheme as an argument to the given styles function, so useEuiFlyoutMenuStyles could be pure.

clintandrewhall added a commit to clintandrewhall/eui that referenced this pull request Jul 23, 2025
Cherry-picked from PR elastic#8851 by tsullivan.

This adds the EuiFlyoutMenu component and managed flyout menu functionality,
including bug fixes, terminology updates, documentation, and stories.
@ryankeairns
Copy link
Contributor

I see the flyout menu bar does not appear on the EuiFlyoutChild stories which leads me to clarify a requirement - the menu bar should always be present on managed flyouts, both parent and child.

In its most minimal state, it would show the close button.

@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

cc @tsullivan

@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

cc @tsullivan

@tkajtoch tkajtoch changed the base branch from main to feat/flyout-system July 25, 2025 10:25
@tkajtoch
Copy link
Member

@tsullivan I updated the base to feat/flyout-system as discussed. Considering this goes to a feature branch now, I'm happy with the current state of this PR. Let me know if you wanna add or address anything else before merging it

@tsullivan tsullivan merged commit 1fb4398 into elastic:feat/flyout-system Jul 25, 2025
5 checks passed
@tsullivan tsullivan deleted the flyout-system/add-top-menu branch July 25, 2025 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

EuiFlyout Add menu bar support for custom actions and links
4 participants