diff --git a/.gitignore b/.gitignore
index 5c1d3b074dd..a125f4c291a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,3 +32,5 @@ yarn-error.log*
!.yarn/sdks
!.yarn/versions
yarn-error.log
+.cursorrules
+WARP.md
diff --git a/packages/eui-theme-borealis/changelogs/upcoming/9202.md b/packages/eui-theme-borealis/changelogs/upcoming/9202.md
new file mode 100644
index 00000000000..33bc5022fd1
--- /dev/null
+++ b/packages/eui-theme-borealis/changelogs/upcoming/9202.md
@@ -0,0 +1 @@
+- Updated parameters used for `euiAnimSlightResistance` for a smoother animation
diff --git a/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json b/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json
index c74b48c0240..de6761797e2 100644
--- a/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json
+++ b/packages/eui-theme-borealis/src/eui_theme_borealis_dark.json
@@ -15,7 +15,7 @@
"euiContrastRatioGraphic": 3,
"euiContrastRatioDisabled": 2,
"euiAnimSlightBounce": "cubic-bezier(0.34, 1.61, 0.7, 1)",
- "euiAnimSlightResistance": "cubic-bezier(0.694, 0.0482, 0.335, 1)",
+ "euiAnimSlightResistance": "cubic-bezier(0.32, 0.72, 0, 1)",
"euiAnimSpeedExtraFast": "90ms",
"euiAnimSpeedFast": "150ms",
"euiAnimSpeedNormal": "250ms",
diff --git a/packages/eui-theme-borealis/src/eui_theme_borealis_light.json b/packages/eui-theme-borealis/src/eui_theme_borealis_light.json
index e3eb735929b..528bdad0991 100644
--- a/packages/eui-theme-borealis/src/eui_theme_borealis_light.json
+++ b/packages/eui-theme-borealis/src/eui_theme_borealis_light.json
@@ -15,7 +15,7 @@
"euiContrastRatioGraphic": 3,
"euiContrastRatioDisabled": 2,
"euiAnimSlightBounce": "cubic-bezier(0.34, 1.61, 0.7, 1)",
- "euiAnimSlightResistance": "cubic-bezier(0.694, 0.0482, 0.335, 1)",
+ "euiAnimSlightResistance": "cubic-bezier(0.32, 0.72, 0, 1)",
"euiAnimSpeedExtraFast": "90ms",
"euiAnimSpeedFast": "150ms",
"euiAnimSpeedNormal": "250ms",
diff --git a/packages/eui-theme-borealis/src/variables/_animation.ts b/packages/eui-theme-borealis/src/variables/_animation.ts
index 84933441db3..5a92ebe4f15 100644
--- a/packages/eui-theme-borealis/src/variables/_animation.ts
+++ b/packages/eui-theme-borealis/src/variables/_animation.ts
@@ -22,7 +22,7 @@ export const animation_speed: _EuiThemeAnimationSpeeds = {
export const animation_ease: _EuiThemeAnimationEasings = {
bounce: 'cubic-bezier(.34, 1.61, .7, 1)',
- resistance: 'cubic-bezier(.694, .0482, .335, 1)',
+ resistance: 'cubic-bezier(.32, .72, 0, 1)',
};
export const animation: _EuiThemeAnimation = {
diff --git a/packages/eui-theme-common/changelogs/upcoming/9202.md b/packages/eui-theme-common/changelogs/upcoming/9202.md
new file mode 100644
index 00000000000..33bc5022fd1
--- /dev/null
+++ b/packages/eui-theme-common/changelogs/upcoming/9202.md
@@ -0,0 +1 @@
+- Updated parameters used for `euiAnimSlightResistance` for a smoother animation
diff --git a/packages/eui-theme-common/src/global_styling/variables/_animations.scss b/packages/eui-theme-common/src/global_styling/variables/_animations.scss
index 93b9daf1641..85b5d0c155a 100644
--- a/packages/eui-theme-common/src/global_styling/variables/_animations.scss
+++ b/packages/eui-theme-common/src/global_styling/variables/_animations.scss
@@ -1,7 +1,7 @@
// Animations
$euiAnimSlightBounce: cubic-bezier(.34, 1.61, .7, 1) !default;
-$euiAnimSlightResistance: cubic-bezier(.694, .0482, .335, 1) !default;
+$euiAnimSlightResistance: cubic-bezier(.32, .72, 0, 1) !default;
$euiAnimSpeedExtraFast: 90ms !default;
$euiAnimSpeedFast: 150ms !default;
diff --git a/packages/eui/changelogs/upcoming/8851.md b/packages/eui/changelogs/upcoming/8851.md
new file mode 100644
index 00000000000..c0e818b0cc1
--- /dev/null
+++ b/packages/eui/changelogs/upcoming/8851.md
@@ -0,0 +1 @@
+Adds a new `EuiFlyoutMenu` component that provides a standardized top menu bar for flyouts.
diff --git a/packages/eui/changelogs/upcoming/8897.md b/packages/eui/changelogs/upcoming/8897.md
new file mode 100644
index 00000000000..d7617700a36
--- /dev/null
+++ b/packages/eui/changelogs/upcoming/8897.md
@@ -0,0 +1 @@
+Flyout system menu bar: require tile, support custom actions
diff --git a/packages/eui/changelogs/upcoming/8999.md b/packages/eui/changelogs/upcoming/8999.md
new file mode 100644
index 00000000000..ad7fd45868e
--- /dev/null
+++ b/packages/eui/changelogs/upcoming/8999.md
@@ -0,0 +1 @@
+- Added a new optional `resizable` (boolean) prop to `EuiFlyout`. Resizability can now be controlled dynamically without the need to use `EuiFlyoutResizable`.
diff --git a/packages/eui/changelogs/upcoming/9003.md b/packages/eui/changelogs/upcoming/9003.md
new file mode 100644
index 00000000000..614ff500158
--- /dev/null
+++ b/packages/eui/changelogs/upcoming/9003.md
@@ -0,0 +1,2 @@
+- Updated `EuiFlyout` with new `onActive` callback and enable stack managed history controls.
+- Updated `EuiFlyoutMenu` with new prop `historyItems` and refactored props for back button.
diff --git a/packages/eui/changelogs/upcoming/9056.md b/packages/eui/changelogs/upcoming/9056.md
new file mode 100644
index 00000000000..8b427e7db0f
--- /dev/null
+++ b/packages/eui/changelogs/upcoming/9056.md
@@ -0,0 +1 @@
+Added a new `hasChildBackground` boolean prop (defaults to false) to `EuiFlyout`
\ No newline at end of file
diff --git a/packages/eui/changelogs/upcoming/9202.md b/packages/eui/changelogs/upcoming/9202.md
new file mode 100644
index 00000000000..1a28880a845
--- /dev/null
+++ b/packages/eui/changelogs/upcoming/9202.md
@@ -0,0 +1,7 @@
+- Added an opt-in EuiFlyout session management for creating flyout compositions and journeys effortlessly. Session management handles side-by-side flyout rendering based on parent-child grouping, simple flyout transitions with history, state sharing, and more.
+ - EuiFlyout session management is an optional feature that can be enabled by adding `session="start"` to EuiFlyout. Check out the [documentation](https://eui.elastic.co/docs/components/containers/flyout/session-management) to learn more.
+
+**Breaking changes**
+
+- Changed the way EuiFlyout renders overlay masks to decouple the overlay mask from the flyout itself. Now, the overlay mask is a separate portalled element.
+ - This change does not modify the functionality or behavior of flyout overlays but might affect some custom usages when your application relies on the specific element nesting within EuiFlyout.
diff --git a/packages/eui/package.json b/packages/eui/package.json
index 17d4cd92aa5..b687b60349e 100644
--- a/packages/eui/package.json
+++ b/packages/eui/package.json
@@ -85,6 +85,7 @@
"unified": "^9.2.2",
"unist-util-visit": "^2.0.3",
"url-parse": "^1.5.10",
+ "use-sync-external-store": "^1.6.0",
"uuid": "^8.3.0",
"vfile": "^4.2.1"
},
diff --git a/packages/eui/src/components/collapsible_nav/__snapshots__/collapsible_nav.test.tsx.snap b/packages/eui/src/components/collapsible_nav/__snapshots__/collapsible_nav.test.tsx.snap
index 1bd264a3928..6d1052f9d55 100644
--- a/packages/eui/src/components/collapsible_nav/__snapshots__/collapsible_nav.test.tsx.snap
+++ b/packages/eui/src/components/collapsible_nav/__snapshots__/collapsible_nav.test.tsx.snap
@@ -2,53 +2,54 @@
exports[`EuiCollapsibleNav close button can be hidden 1`] = `
-
-
+
+
+
-
-
-
-
+ You are in a modal dialog. Press Escape or tap/click outside the dialog on the shadowed overlay to close.
+
+
+
+
+
`;
@@ -56,55 +57,56 @@ exports[`EuiCollapsibleNav does not render if isOpen is false 1`] = `
`;
exports[`EuiCollapsibleNav is rendered 1`] = `
-
-
+
+
+
-
-
-
-
+ You are in a modal dialog. Press Escape or tap/click outside the dialog on the shadowed overlay to close.
+
+
+
+
+
`;
@@ -125,7 +127,7 @@ exports[`EuiCollapsibleNav props accepts EuiFlyout props 1`] = `
data-autofocus="true"
id="id"
role="dialog"
- style="inline-size: 240px;"
+ style="inline-size: 240px; z-index: 6000;"
tabindex="0"
>
-
-
+
+
+
-
-
-
-
+ You are in a modal dialog. Press Escape or tap/click outside the dialog on the shadowed overlay to close.
+
+
+
+
+
`;
exports[`EuiCollapsibleNav props dockedBreakpoint 1`] = `
-
-
+
+
+
-
-
-
-
+ You are in a modal dialog. Press Escape or tap/click outside the dialog on the shadowed overlay to close.
+
+
+
+
+
`;
@@ -280,7 +284,7 @@ exports[`EuiCollapsibleNav props isDocked 1`] = `
-
-
+
+
+
-
-
-
-
+ You are in a modal dialog. Press Escape or tap/click outside the dialog on the shadowed overlay to close.
+
+
+
+
+
`;
@@ -361,7 +366,7 @@ exports[`EuiCollapsibleNav props showButtonIfDocked 1`] = `
-
-
+
+
+
-
-
-
-
+ You are in a modal dialog. Press Escape or tap/click outside the dialog on the shadowed overlay to close.
+
+
+
+
+
`;
diff --git a/packages/eui/src/components/collapsible_nav/collapsible_nav.spec.tsx b/packages/eui/src/components/collapsible_nav/collapsible_nav.spec.tsx
index e08c0850295..36eb11224af 100644
--- a/packages/eui/src/components/collapsible_nav/collapsible_nav.spec.tsx
+++ b/packages/eui/src/components/collapsible_nav/collapsible_nav.spec.tsx
@@ -67,7 +67,13 @@ describe('EuiCollapsibleNav', () => {
it('closes the nav when the overlay mask is clicked', () => {
cy.realMount(
);
cy.get('[data-test-subj="navSpecButton"]').realClick();
+
+ // wait is used here because cypress
+ // thinks the overlay is covered due to our position: fixed style.
+ // This is likely fixed in more recent versions of Cypress
+ cy.wait(0);
cy.get('.euiOverlayMask').realClick({ position: 'bottomRight' });
+
expect(cy.get('#navSpec').should('not.exist'));
});
diff --git a/packages/eui/src/components/collapsible_nav/collapsible_nav.tsx b/packages/eui/src/components/collapsible_nav/collapsible_nav.tsx
index d2216ab948a..90661f68bcd 100644
--- a/packages/eui/src/components/collapsible_nav/collapsible_nav.tsx
+++ b/packages/eui/src/components/collapsible_nav/collapsible_nav.tsx
@@ -116,6 +116,7 @@ export const EuiCollapsibleNav: FunctionComponent
= ({
const flyout = (
Nav content
@@ -92,7 +92,7 @@ exports[`EuiCollapsibleNavBeta renders initialIsCollapsed 1`] = `
class="euiFlyout euiCollapsibleNav euiCollapsibleNavBeta emotion-euiFlyout-none-noMaxWidth-push-left-noAnimation-left-euiCollapsibleNavBeta-isPush-left-isPushCollapsed"
data-test-subj="nav"
id="generated-id_euiCollapsibleNav"
- style="inline-size: 48px;"
+ style="inline-size: 48px; z-index: 1000;"
>
Nav content
diff --git a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_beta.tsx b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_beta.tsx
index c7256e16fb4..56c8fe8e9d5 100644
--- a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_beta.tsx
+++ b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_beta.tsx
@@ -35,7 +35,7 @@ import { EuiCollapsibleNavButton } from './collapsible_nav_button';
import { euiCollapsibleNavBetaStyles } from './collapsible_nav_beta.styles';
export type EuiCollapsibleNavBetaProps = CommonProps &
- HTMLAttributes &
+ Omit, 'onResize'> &
Pick<
EuiFlyoutProps, // Extend only specific flyout props - EuiCollapsibleNav is much less customizable than EuiFlyout
'side' | 'focusTrapProps' | 'includeFixedHeadersInFocusTrap'
@@ -211,6 +211,7 @@ const _EuiCollapsibleNavBeta: FunctionComponent = ({
aria-label={defaultAriaLabel}
{...rest} // EuiCollapsibleNav is significantly less permissive than EuiFlyout
id={flyoutID}
+ session="never"
css={cssStyles}
className={classes}
size={width}
diff --git a/packages/eui/src/components/collapsible_nav_beta/context.ts b/packages/eui/src/components/collapsible_nav_beta/context.ts
index 7ae67a730a9..f2c21265a9a 100644
--- a/packages/eui/src/components/collapsible_nav_beta/context.ts
+++ b/packages/eui/src/components/collapsible_nav_beta/context.ts
@@ -8,7 +8,7 @@
import { createContext, MouseEventHandler } from 'react';
-import { _EuiFlyoutSide } from '../flyout/flyout';
+import { _EuiFlyoutSide } from '../flyout/const';
type _EuiCollapsibleNavContext = {
isCollapsed: boolean;
diff --git a/packages/eui/src/components/flyout/README.md b/packages/eui/src/components/flyout/README.md
new file mode 100644
index 00000000000..ddad71b70ba
--- /dev/null
+++ b/packages/eui/src/components/flyout/README.md
@@ -0,0 +1,56 @@
+# EuiFlyout
+
+[Documentation - production](https://eui.elastic.co/docs/components/containers/flyout/)
+
+[Documentation - local](http://localhost:3000/docs/components/containers/flyout/)
+
+[Documentation - sources](../../../../website/docs/components/containers/flyout)
+
+## Component composition
+
+```mermaid
+flowchart
+ EuiFlyout --> EuiFlyoutComponent
+ EuiFlyout --> |"session = 'start'"|EuiFlyoutMain --> EuiManagedFlyout --> EuiFlyoutComponent
+ EuiFlyout --> |"session = 'inherit'"|EuiFlyoutChild --> EuiManagedFlyout --> EuiFlyoutComponent
+ EuiFlyout --> |"nested + session undefined"|EuiFlyoutChild
+```
+
+The core implementation of EuiFlyout lives in the internal [EuiFlyoutComponent](./flyout.component.tsx) file.
+It contains the main logic and UI for rendering flyouts. However, it's not the component
+that EUI consumers interact with directly.
+
+The EuiFlyout export actually comes from [`flyout.tsx`](./flyout.tsx) which is a thin logical
+wrapper that conditionally routes to different implementations:
+- `session="start"` → [EuiFlyoutMain](./manager/flyout_main.tsx) (creates new session)
+- `session="inherit"` → [EuiFlyoutChild](./manager/flyout_child.tsx) (joins existing session)
+- `session="never"` → [EuiFlyoutComponent](./flyout.component.tsx) (standard flyout)
+- `session` undefined + nested inside parent → [EuiFlyoutChild](./manager/flyout_child.tsx) (auto-inherits)
+- `session` undefined + not nested → [EuiFlyoutComponent](./flyout.component.tsx) (standard flyout)
+
+This structure provides better business logic separation and enables intuitive nested flyout behavior.
+
+## Resizable flyouts
+
+Historically, the resizable variant of EuiFlyout was a separate component called
+[EuiFlyoutResizable](./flyout_resizable.tsx). It was a wrapper over the regular `EuiFlyout` that injected
+additional event handlers and a drag handler element to flyout's `children`.
+
+Currently, this logic is moved to an internal [`useEuiFlyoutResizable`](./use_flyout_resizable.ts) hook
+that serves the same purpose, but is directly integrated into EuiFlyoutComponent,
+and the resizability feature is enabled via the `resizable` prop for simplicity and ability
+to dynamically change whether the flyout is resizable or not.
+
+The EuiFlyoutResizable component still exists as a thin wrapper over EuiFlyout
+that sets the `resizable` prop to `true`, and is exported as part of the public API
+for backwards compatibility.
+
+```mermaid
+flowchart
+ EuiFlyoutResizable --> EuiFlyoutComponent
+ EuiFlyoutComponent ~~~|"resizable = true"| EuiFlyoutComponent
+```
+
+## Managed flyouts (aka flyout session management)
+
+The developer README for the managed flyouts lives in the [`manager` subdirectory](./manager/README.md).
diff --git a/packages/eui/src/components/flyout/__snapshots__/flyout.test.tsx.snap b/packages/eui/src/components/flyout/__snapshots__/flyout.test.tsx.snap
index 82f4c313eeb..b68c50a85a6 100644
--- a/packages/eui/src/components/flyout/__snapshots__/flyout.test.tsx.snap
+++ b/packages/eui/src/components/flyout/__snapshots__/flyout.test.tsx.snap
@@ -5,53 +5,55 @@ exports[`EuiFlyout is rendered 1`] = `
class="euiBody--hasFlyout"
>
-
+
+
+
-
-
-
- You are in a modal dialog. Press Escape or tap/click outside the dialog on the shadowed overlay to close.
-
-
-
-
+ You are in a modal dialog. Press Escape or tap/click outside the dialog on the shadowed overlay to close.
+
+
+
-
+