diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiAutoRefresh_EuiAutoRefreshButton_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiAutoRefresh_EuiAutoRefreshButton_Playground.png
index 7fa6a1adfa8..b7042da2aaf 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiAutoRefresh_EuiAutoRefreshButton_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiAutoRefresh_EuiAutoRefreshButton_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiAutoRefresh_EuiAutoRefresh_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiAutoRefresh_EuiAutoRefresh_Playground.png
index a2c6fb8fa5d..da10d5a2ea4 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiAutoRefresh_EuiAutoRefresh_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiAutoRefresh_EuiAutoRefresh_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiComboBox_Groups.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiComboBox_Groups.png
index 38a2db062f5..6f699a50ec6 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiComboBox_Groups.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiComboBox_Groups.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiComboBox_Nested_Options_Groups.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiComboBox_Nested_Options_Groups.png
index 38a2db062f5..6f699a50ec6 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiComboBox_Nested_Options_Groups.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiComboBox_Nested_Options_Groups.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Playground.png
index 2afc5775f24..c4a961b6415 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Restricted_Day_Select.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Restricted_Day_Select.png
index 41df97e6918..bf3953d37be 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Restricted_Day_Select.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Restricted_Day_Select.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select.png
index 3678147fcf4..8196c1f80c4 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select_Only.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select_Only.png
index 5e62e1a3732..c43ab3fe28f 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select_Only.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiDatePicker_Time_Select_Only.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Custom_Quick_Select_Panel.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Custom_Quick_Select_Panel.png
index 0ed7e06c6d5..c76efb162dc 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Custom_Quick_Select_Panel.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Custom_Quick_Select_Panel.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Playground.png
index 0ed7e06c6d5..35521170bbb 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiHeader_EuiHeaderLinks_Playground.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiHeader_EuiHeaderLinks_Playground.png
index 6653d562191..a41e1c1cd15 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiHeader_EuiHeaderLinks_Playground.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiHeader_EuiHeaderLinks_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiHeader_EuiHeader_Dark_Theme_With_Sitewide_Search.png b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiHeader_EuiHeader_Dark_Theme_With_Sitewide_Search.png
index 73dff6354a0..3881dab7904 100644
Binary files a/packages/eui/.loki/reference/chrome_desktop_Layout_EuiHeader_EuiHeader_Dark_Theme_With_Sitewide_Search.png and b/packages/eui/.loki/reference/chrome_desktop_Layout_EuiHeader_EuiHeader_Dark_Theme_With_Sitewide_Search.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiAutoRefresh_EuiAutoRefreshButton_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiAutoRefresh_EuiAutoRefreshButton_Playground.png
index fb60ed6cca2..017e5ac6d43 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiAutoRefresh_EuiAutoRefreshButton_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiAutoRefresh_EuiAutoRefreshButton_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiAutoRefresh_EuiAutoRefresh_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiAutoRefresh_EuiAutoRefresh_Playground.png
index 925ab912d1d..fd924ac4fe2 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiAutoRefresh_EuiAutoRefresh_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiAutoRefresh_EuiAutoRefresh_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiComboBox_Groups.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiComboBox_Groups.png
index bd00849b0b8..661b6537bdb 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiComboBox_Groups.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiComboBox_Groups.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiComboBox_Nested_Options_Groups.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiComboBox_Nested_Options_Groups.png
index bd00849b0b8..661b6537bdb 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiComboBox_Nested_Options_Groups.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiComboBox_Nested_Options_Groups.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Playground.png
index 94c44ecdbf7..c47290a1b4b 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Restricted_Day_Select.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Restricted_Day_Select.png
index b43c64c987b..9159441dff0 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Restricted_Day_Select.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Restricted_Day_Select.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select.png
index 80a55d2f4f2..a87e7ba5261 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select_Only.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select_Only.png
index a939092c2af..adfa6857b3a 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select_Only.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiDatePicker_Time_Select_Only.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Custom_Quick_Select_Panel.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Custom_Quick_Select_Panel.png
index fa3393a4c64..28a69a24121 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Custom_Quick_Select_Panel.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Custom_Quick_Select_Panel.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Playground.png
index fa3393a4c64..32277cccdf5 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Forms_EuiSuperDatePicker_EuiSuperDatePicker_Playground.png differ
diff --git a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiHeader_EuiHeaderLinks_Playground.png b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiHeader_EuiHeaderLinks_Playground.png
index 7e8da064785..8298908276c 100644
Binary files a/packages/eui/.loki/reference/chrome_mobile_Layout_EuiHeader_EuiHeaderLinks_Playground.png and b/packages/eui/.loki/reference/chrome_mobile_Layout_EuiHeader_EuiHeaderLinks_Playground.png differ
diff --git a/packages/eui/.storybook/loki.ts b/packages/eui/.storybook/loki.ts
index 06770517202..9c8879cb44b 100644
--- a/packages/eui/.storybook/loki.ts
+++ b/packages/eui/.storybook/loki.ts
@@ -25,12 +25,7 @@ export const LOKI_SELECTORS = {
/**
* Portal element content selector
*/
- portal: '[data-euiportal="true"]',
- /**
- * Body selector
- * TODO: remove when LOKI_SELECTORS.portal selector works as expected again
- */
- body: 'body',
+ portal: '#storybook-root',
} as const;
/**
diff --git a/packages/eui/.storybook/preview.tsx b/packages/eui/.storybook/preview.tsx
index d8be14a6169..385ee472dff 100644
--- a/packages/eui/.storybook/preview.tsx
+++ b/packages/eui/.storybook/preview.tsx
@@ -10,6 +10,7 @@
import React from 'react';
import type { Preview } from '@storybook/react';
+import { useState, useMemo } from '@storybook/preview-api';
import { MINIMAL_VIEWPORTS } from '@storybook/addon-viewport';
/*
@@ -57,24 +58,41 @@ import { hideStorybookControls } from './utils';
const preview: Preview = {
decorators: [
customJsxDecorator,
- (Story, context) => (
-
- */
- id="story-wrapper"
- css={[
- writingModeStyles.writingMode,
- // @ts-ignore - we're manually ensuring `writingMode` globals match our Emotion style keys
- writingModeStyles[context.globals.writingMode],
- ]}
+ (Story, context) => {
+ const [portalSibling, setPortalSibling] = useState(
+ null
+ );
+ const portalInsert = useMemo(() => {
+ if (portalSibling) {
+ return {
+ EuiPortal: {
+ insert: { sibling: portalSibling, position: 'after' as const },
+ },
+ };
+ }
+ }, [portalSibling]);
+
+ return (
+
-
-
-
- ),
+ */
+ id="story-wrapper"
+ css={[
+ writingModeStyles.writingMode,
+ // @ts-ignore - we're manually ensuring `writingMode` globals match our Emotion style keys
+ writingModeStyles[context.globals.writingMode],
+ ]}
+ >
+ {portalInsert && }
+
+
+ );
+ },
],
globalTypes: {
colorMode: {
diff --git a/packages/eui/.storybook/test.ts b/packages/eui/.storybook/test.ts
new file mode 100644
index 00000000000..0cc66d08a92
--- /dev/null
+++ b/packages/eui/.storybook/test.ts
@@ -0,0 +1,46 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { queries, within, waitFor, fireEvent, expect } from '@storybook/test';
+import * as dataTestSubjQueries from '../src/test/rtl/data_test_subj_queries';
+
+/**
+ * Custom Storybook within util with EUI query helpers
+ * + additional chained async/waitFor component utils
+ *
+ * @see https://storybook.js.org/docs/writing-stories/play-function#writing-stories-with-the-play-function
+ * @see https://testing-library.com/docs/dom-testing-library/api-within/
+ */
+const customWithin = (canvasElement: HTMLElement) => {
+ const canvas = within(
+ canvasElement,
+ { ...queries, ...dataTestSubjQueries }
+ );
+
+ return {
+ ...canvas,
+
+ /**
+ * 1. Loki doesn't like userEvent, only fireEvent
+ * 2. Storybook fires fireEvents too early (esp. on page load), so we add a waitFor
+ */
+ waitForAndClick: async (testSubject: string) => {
+ await waitFor(() =>
+ expect(canvas.getByTestSubject(testSubject)).toBeInTheDocument()
+ );
+ await fireEvent.click(canvas.getByTestSubject(testSubject));
+ },
+
+ waitForEuiPopoverVisible: async () =>
+ await waitFor(() =>
+ expect(canvasElement.querySelector('[data-popover-open]')).toBeVisible()
+ ),
+ };
+};
+
+export { customWithin as within };
diff --git a/packages/eui/changelogs/upcoming/8003.md b/packages/eui/changelogs/upcoming/8003.md
new file mode 100644
index 00000000000..456e5c1fead
--- /dev/null
+++ b/packages/eui/changelogs/upcoming/8003.md
@@ -0,0 +1,3 @@
+**Bug fixes**
+
+- Fixed `EuiPopover` to correctly inherit from `EuiProvider`'s `componentDefaults.EuiPortal.insert`
diff --git a/packages/eui/src/components/combo_box/combo_box.stories.tsx b/packages/eui/src/components/combo_box/combo_box.stories.tsx
index c65dcb5aaba..880c9d93496 100644
--- a/packages/eui/src/components/combo_box/combo_box.stories.tsx
+++ b/packages/eui/src/components/combo_box/combo_box.stories.tsx
@@ -139,7 +139,7 @@ export const Groups: Story = {
include: ['options'],
},
loki: {
- chromeSelector: LOKI_SELECTORS.body,
+ chromeSelector: LOKI_SELECTORS.portal,
},
},
args: {
@@ -167,7 +167,7 @@ export const NestedOptionsGroups: Story = {
include: ['options'],
},
loki: {
- chromeSelector: LOKI_SELECTORS.body,
+ chromeSelector: LOKI_SELECTORS.portal,
},
},
args: {
diff --git a/packages/eui/src/components/date_picker/auto_refresh/auto_refresh.stories.tsx b/packages/eui/src/components/date_picker/auto_refresh/auto_refresh.stories.tsx
index 0da22bd1990..e538b50e4a8 100644
--- a/packages/eui/src/components/date_picker/auto_refresh/auto_refresh.stories.tsx
+++ b/packages/eui/src/components/date_picker/auto_refresh/auto_refresh.stories.tsx
@@ -7,10 +7,12 @@
*/
import type { Meta, StoryObj } from '@storybook/react';
-
+import { fireEvent, waitFor } from '@storybook/test';
+import { within } from '../../../../.storybook/test';
+import { LOKI_SELECTORS } from '../../../../.storybook/loki';
import { enableFunctionToggleControls } from '../../../../.storybook/utils';
-import { REFRESH_UNIT_OPTIONS } from '../types';
+import { REFRESH_UNIT_OPTIONS } from '../types';
import { EuiAutoRefresh, EuiAutoRefreshProps } from './auto_refresh';
const meta: Meta = {
@@ -18,8 +20,7 @@ const meta: Meta = {
component: EuiAutoRefresh,
parameters: {
loki: {
- // TODO: uncomment once loki CLI is fixed for portal component stories
- // chromeSelector: LOKI_SELECTORS.portal,
+ chromeSelector: LOKI_SELECTORS.portal,
},
},
argTypes: {
@@ -42,15 +43,13 @@ export default meta;
type Story = StoryObj;
export const Playground: Story = {
- // TODO: uncomment once loki CLI is fixed for portal component stories
- // play: lokiPlayDecorator(async (context) => {
- // const { bodyElement, step } = context;
- // const canvas = within(bodyElement);
- // await step('show popover on click of the input', async () => {
- // await userEvent.click(canvas.getByLabelText('Auto refresh'));
- // await waitFor(() => {
- // expect(canvas.getByRole('dialog')).toBeVisible();
- // });
- // });
- // }),
+ play: async ({ canvasElement, step }) => {
+ const canvas = within(canvasElement);
+ await step('show popover on click', async () => {
+ await waitFor(async () => {
+ await fireEvent.click(canvas.getByLabelText('Auto refresh'));
+ });
+ await canvas.waitForEuiPopoverVisible();
+ });
+ },
};
diff --git a/packages/eui/src/components/date_picker/date_picker.stories.tsx b/packages/eui/src/components/date_picker/date_picker.stories.tsx
index 4f1d681f66f..d8d51d6f3e1 100644
--- a/packages/eui/src/components/date_picker/date_picker.stories.tsx
+++ b/packages/eui/src/components/date_picker/date_picker.stories.tsx
@@ -9,12 +9,14 @@
import React, { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import moment from 'moment';
-
+import { fireEvent, waitFor } from '@storybook/test';
+import { within } from '../../../.storybook/test';
+import { LOKI_SELECTORS } from '../../../.storybook/loki';
import {
disableStorybookControls,
enableFunctionToggleControls,
} from '../../../.storybook/utils';
-import { LOKI_SELECTORS } from '../../../.storybook/loki';
+
import {
EuiDatePicker,
EuiDatePickerProps,
@@ -119,6 +121,16 @@ const meta: Meta = {
selected: null,
utcOffset: undefined,
},
+ // Open the datepicker automatically for Loki VRT
+ play: async ({ canvasElement, step }) => {
+ const canvas = within(canvasElement);
+ await step('show popover on click', async () => {
+ await waitFor(async () => {
+ await fireEvent.click(canvas.getByRole('textbox'));
+ });
+ await canvas.waitForEuiPopoverVisible();
+ });
+ },
};
disableStorybookControls(meta, ['inputRef']);
enableFunctionToggleControls(meta, ['onClear', 'onChange']);
@@ -135,9 +147,6 @@ export const Playground: Story = {
},
},
args: {
- // NOTE: loki play interactions won't work in CLI somehow
- // TODO: exchange with loki play() interactions once fixed
- autoFocus: true,
// setting a selected date to ensure VRT does not
// automatically updated based on the current date
selected: moment('Tue Mar 19 2024 18:54:51 GMT+0100'),
@@ -162,7 +171,6 @@ export const TimeSelect: Story = {
},
},
args: {
- autoFocus: true, // Open the datepicker automatically for Loki VRT
showTimeSelect: true,
showTimeSelectOnly: false,
selected: moment('01/01/1970').hours(23).minutes(0),
@@ -191,7 +199,6 @@ export const RestrictedDaySelect: Story = {
},
},
args: {
- autoFocus: true, // Open the datepicker automatically for Lok VRT,
selected: moment('01/02/1970'),
maxDate: moment('01/01/1970'),
minDate: moment('12/31/1969'),
diff --git a/packages/eui/src/components/date_picker/super_date_picker/super_date_picker.stories.tsx b/packages/eui/src/components/date_picker/super_date_picker/super_date_picker.stories.tsx
index be308e909ca..528d9baf4b3 100644
--- a/packages/eui/src/components/date_picker/super_date_picker/super_date_picker.stories.tsx
+++ b/packages/eui/src/components/date_picker/super_date_picker/super_date_picker.stories.tsx
@@ -8,8 +8,11 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
-
+import { expect } from '@storybook/test';
+import { within } from '../../../../.storybook/test';
+import { LOKI_SELECTORS } from '../../../../.storybook/loki';
import { enableFunctionToggleControls } from '../../../../.storybook/utils';
+
import { EuiLink } from '../../link';
import { ApplyTime, REFRESH_UNIT_OPTIONS } from '../types';
@@ -21,12 +24,6 @@ import {
const meta: Meta = {
title: 'Forms/EuiSuperDatePicker/EuiSuperDatePicker',
component: EuiSuperDatePicker,
- parameters: {
- loki: {
- // TODO: uncomment once loki CLI is fixed for portal component stories
- // chromeSelector: LOKI_SELECTORS.portal,
- },
- },
argTypes: {
refreshIntervalUnits: {
control: 'radio',
@@ -70,6 +67,9 @@ export const CustomQuickSelectPanel: Story = {
controls: {
include: ['customQuickSelectPanels', 'onTimeChange'],
},
+ loki: {
+ chromeSelector: LOKI_SELECTORS.portal,
+ },
},
args: {
customQuickSelectPanels: [
@@ -79,18 +79,14 @@ export const CustomQuickSelectPanel: Story = {
},
],
},
- // TODO: uncomment once loki CLI is fixed for portal component stories
- // play: lokiPlayDecorator(async (context) => {
- // const { bodyElement, step } = context;
- // const canvas = within(bodyElement);
- // await step('show popover on click of the quick select button', async () => {
- // await userEvent.click(canvas.getByLabelText('Date quick select'));
- // await waitFor(() => {
- // expect(canvas.getByRole('dialog')).toBeVisible();
- // expect(canvas.getByText('Custom quick select panel')).toBeVisible();
- // });
- // });
- // }),
+ play: async ({ canvasElement, step }) => {
+ const canvas = within(canvasElement);
+ await step('show popover on click of the quick select button', async () => {
+ canvas.waitForAndClick('superDatePickerToggleQuickMenuButton');
+ await canvas.waitForEuiPopoverVisible();
+ expect(canvas.getByText('Custom quick select panel')).toBeVisible();
+ });
+ },
};
function CustomPanel({ applyTime }: { applyTime?: ApplyTime }) {
diff --git a/packages/eui/src/components/header/header.stories.tsx b/packages/eui/src/components/header/header.stories.tsx
index 7b4d45767cc..a10a86299b6 100644
--- a/packages/eui/src/components/header/header.stories.tsx
+++ b/packages/eui/src/components/header/header.stories.tsx
@@ -90,7 +90,7 @@ export const DarkThemeWithSitewideSearch: Story = {
parameters: {
layout: 'fullscreen',
controls: { include: ['theme'] },
- loki: { chromeSelector: LOKI_SELECTORS.body }, // Required to capture the open popover
+ loki: { chromeSelector: LOKI_SELECTORS.portal }, // Required to capture the open popover
},
args: {
theme: 'dark',
@@ -155,8 +155,8 @@ export const DarkThemeWithSitewideSearch: Story = {
};
const MultipleFixedHeadersExample = () => {
- const [fixedHeadersCount, setFixedHeadersCount] = useState(3); // eslint-disable-line react-hooks/rules-of-hooks
- const [isFlyoutOpen, setIsFlyoutOpen] = useState(false); // eslint-disable-line react-hooks/rules-of-hooks
+ const [fixedHeadersCount, setFixedHeadersCount] = useState(3);
+ const [isFlyoutOpen, setIsFlyoutOpen] = useState(false);
const sections = [
{
diff --git a/packages/eui/src/components/header/header_links/header_links.stories.tsx b/packages/eui/src/components/header/header_links/header_links.stories.tsx
index 982146901ee..32eeb36d6f7 100644
--- a/packages/eui/src/components/header/header_links/header_links.stories.tsx
+++ b/packages/eui/src/components/header/header_links/header_links.stories.tsx
@@ -8,6 +8,8 @@
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
+import { fireEvent, waitFor } from '@storybook/test';
+import { within } from '../../../../.storybook/test';
import { LOKI_SELECTORS } from '../../../../.storybook/loki';
import { EuiHeader, EuiHeaderSection, EuiHeaderSectionItem } from '../';
@@ -22,11 +24,9 @@ const meta: Meta = {
// Component defaults
gutterSize: 's',
popoverBreakpoints: ['xs', 's'],
- // VRT
- popoverProps: { isOpen: true },
},
// Required to capture mobile popover
- parameters: { loki: { chromeSelector: LOKI_SELECTORS.body } },
+ parameters: { loki: { chromeSelector: LOKI_SELECTORS.portal } },
};
export default meta;
@@ -46,4 +46,18 @@ export const Playground: Story = {
),
+ play: async ({ canvasElement, step }) => {
+ const canvas = within(canvasElement);
+ await waitFor(() => canvas.getByLabelText('App menu')); // Wait for rendering to finish
+
+ step('Open mobile popover', async () => {
+ await waitFor(async () => {
+ const mobilePopover = canvas.queryByLabelText('Open menu');
+ if (mobilePopover) {
+ await fireEvent.click(mobilePopover);
+ await canvas.waitForEuiPopoverVisible();
+ }
+ });
+ });
+ },
};
diff --git a/packages/eui/src/components/popover/popover.spec.tsx b/packages/eui/src/components/popover/popover.spec.tsx
index 926391dbf89..811a995b83b 100644
--- a/packages/eui/src/components/popover/popover.spec.tsx
+++ b/packages/eui/src/components/popover/popover.spec.tsx
@@ -10,7 +10,13 @@
///
///
-import React, { useState, FC, MouseEventHandler } from 'react';
+import React, {
+ useState,
+ useEffect,
+ FC,
+ MouseEventHandler,
+ PropsWithChildren,
+} from 'react';
import { EuiButton, EuiConfirmModal } from '../../components';
import { EuiPopover, EuiPopoverProps } from './popover';
@@ -182,8 +188,10 @@ describe('EuiPopover', () => {
// Assert that the popover rendered horizontally and not vertically
cy.get('[data-popover-panel]')
.invoke('offset')
- .then(({ top, left }) => {
- expect(left).to.be.gt(top);
+ .then((offset) => {
+ if (offset) {
+ expect(offset.left).to.be.gt(offset.top);
+ }
});
});
@@ -201,9 +209,69 @@ describe('EuiPopover', () => {
// Assert that the popover vertically and not horizontally
cy.get('[data-popover-panel]')
.invoke('offset')
- .then(({ top, left }) => {
- expect(top).to.be.gt(left);
+ .then((offset) => {
+ if (offset) {
+ expect(offset.top).to.be.gt(offset.left);
+ }
});
});
});
+
+ describe('insert', () => {
+ const sibling = document.createElement('div');
+ sibling.id = 'sibling';
+ const componentDefaults = {
+ EuiPortal: { insert: { sibling, position: 'before' as const } },
+ };
+
+ const Wrapper: FC = ({ children }) => {
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ document.body.appendChild(sibling);
+ setMounted(true);
+ }, []);
+
+ return <>{mounted && children}>;
+ };
+
+ it('inherits from componentDefaults.EuiPortal', () => {
+ cy.mount(
+
+
+ ,
+ { providerProps: { componentDefaults } }
+ );
+
+ // verify the popover was appended before the sibling
+ cy.get('div[data-euiportal]').then((portal) => {
+ cy.get('div#sibling').then((sibling) => {
+ expect(portal).to.have.lengthOf(1);
+ expect(sibling).to.have.lengthOf(1);
+ expect(sibling.get(0).previousElementSibling).to.equal(portal.get(0));
+ });
+ });
+ });
+
+ it('still allows overriding defaults via component props', () => {
+ cy.mount(
+
+
+ ,
+ { providerProps: { componentDefaults } }
+ );
+
+ // verify portal elements were appended before and after the sibling
+ cy.get('div[data-euiportal]').then((portal) => {
+ cy.get('div#sibling').then((sibling) => {
+ expect(portal).to.have.lengthOf(1);
+ expect(sibling).to.have.lengthOf(1);
+ expect(sibling.get(0).nextElementSibling).to.equal(portal.get(0));
+ });
+ });
+ });
+ });
});
diff --git a/packages/eui/src/components/popover/popover.tsx b/packages/eui/src/components/popover/popover.tsx
index e31db77517b..78c13b94226 100644
--- a/packages/eui/src/components/popover/popover.tsx
+++ b/packages/eui/src/components/popover/popover.tsx
@@ -709,7 +709,7 @@ export class EuiPopover extends Component {
const returnFocus = this.state.isOpenStable ? returnFocusConfig : false;
panel = (
-
+
///
-import React, { useState, useEffect, FunctionComponent } from 'react';
+import React, {
+ useState,
+ useEffect,
+ FunctionComponent,
+ PropsWithChildren,
+} from 'react';
import { EuiPortal, EuiPortalProps } from './portal';
@@ -130,7 +135,7 @@ describe('EuiPortal', () => {
const sibling = document.createElement('div');
sibling.id = 'sibling';
- const Wrapper: FunctionComponent = ({ children }) => {
+ const Wrapper: FunctionComponent = ({ children }) => {
const [mounted, setMounted] = useState(false);
useEffect(() => {