(
+
+ ),
+ },
+ ]}
+ />
+ );
+ fireEvent.click(getByTestSubject('euiCollapsedNavButton'));
+ await waitForEuiPopoverOpen();
+
+ fireEvent.click(getByTestSubject('custom'));
+ await waitForEuiPopoverClose();
+ });
});
diff --git a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsed/collapsed_nav_popover.tsx b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsed/collapsed_nav_popover.tsx
index 7a4ef740c60..7ce254b4877 100644
--- a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsed/collapsed_nav_popover.tsx
+++ b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsed/collapsed_nav_popover.tsx
@@ -6,21 +6,26 @@
* Side Public License, v 1.
*/
-import React, { FunctionComponent, useState, useCallback } from 'react';
+import React, {
+ FunctionComponent,
+ MouseEvent,
+ useState,
+ useCallback,
+ useContext,
+} from 'react';
import { useEuiMemoizedStyles } from '../../../../services';
-
import {
type EuiPopoverProps,
EuiPopover,
EuiPopoverTitle,
} from '../../../popover';
+import { EuiCollapsibleNavContext } from '../../context';
import {
EuiCollapsibleNavSubItem,
EuiCollapsibleNavItemProps,
} from '../collapsible_nav_item';
-
import { EuiCollapsedNavButton } from './collapsed_nav_button';
import { euiCollapsedNavPopoverStyles } from './collapsed_nav_popover.styles';
@@ -48,6 +53,20 @@ export const EuiCollapsedNavPopover: FunctionComponent<
);
const closePopover = useCallback(() => setIsPopoverOpen(false), []);
+ const closePopoverClick = useCallback(
+ (event: MouseEvent) => {
+ closePopover();
+ // Visually hide the tooltip for mouse users only
+ const isMouseEvent = event.screenX !== 0 && event.screenY !== 0;
+ if (isMouseEvent) setIsTooltipHidden(true);
+ },
+ [closePopover]
+ );
+ const [isTooltipHidden, setIsTooltipHidden] = useState(false);
+ const reshowTooltip = useCallback(() => setIsTooltipHidden(false), []);
+
+ const navContext = useContext(EuiCollapsibleNavContext);
+
return (
}
{...rest}
@@ -81,9 +101,13 @@ export const EuiCollapsedNavPopover: FunctionComponent<
- {items!.map((item, index) => (
-
- ))}
+
+ {items!.map((item, index) => (
+
+ ))}
+
);
diff --git a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsible_nav_item.tsx b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsible_nav_item.tsx
index b1b9bc71c7f..311e94a697c 100644
--- a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsible_nav_item.tsx
+++ b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsible_nav_item.tsx
@@ -9,6 +9,7 @@
import React, {
FunctionComponent,
HTMLAttributes,
+ MouseEventHandler,
ReactNode,
useContext,
useMemo,
@@ -103,7 +104,16 @@ export type EuiCollapsibleNavItemProps = _SharedEuiCollapsibleNavItemProps & {
>;
export type EuiCollapsibleNavCustomSubItem = {
- renderItem: () => ReactNode;
+ renderItem: (options: {
+ /**
+ * When the side nav is collapsed on larger screens, the menu appears in an EuiPopover.
+ * When the sidenav is collapsed on smaller screens, the menu appears in an EuiFlyout.
+ *
+ * Use this handler to close either the portalled flyout or popover, depending on which is present.
+ * If the handler is not defined, it means there is no portal onscreen to close.
+ */
+ closePortals?: MouseEventHandler;
+ }) => ReactNode;
};
export type EuiCollapsibleNavSubItemProps = ExclusiveUnion<
@@ -229,9 +239,10 @@ export const EuiCollapsibleNavSubItem: FunctionComponent<
EuiCollapsibleNavSubItemProps
> = ({ renderItem, className, ...props }) => {
const classes = classNames('euiCollapsibleNavSubItem', className);
+ const { closePortals } = useContext(EuiCollapsibleNavContext);
if (renderItem) {
- return <>{renderItem()}>;
+ return <>{renderItem({ closePortals })}>;
}
return (
diff --git a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsible_nav_link.tsx b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsible_nav_link.tsx
index eba54251b86..99bee4f1e3e 100644
--- a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsible_nav_link.tsx
+++ b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/collapsible_nav_link.tsx
@@ -6,12 +6,18 @@
* Side Public License, v 1.
*/
-import React, { FunctionComponent, ReactNode } from 'react';
+import React, {
+ FunctionComponent,
+ ReactNode,
+ useCallback,
+ useContext,
+} from 'react';
import classNames from 'classnames';
import { useEuiMemoizedStyles } from '../../../services';
import { EuiLink, EuiLinkProps } from '../../link';
+import { EuiCollapsibleNavContext } from '../context';
import type {
_SharedEuiCollapsibleNavItemProps,
_EuiCollapsibleNavItemDisplayProps,
@@ -71,11 +77,25 @@ export const EuiCollapsibleNavLink: FunctionComponent<
isInteractive && linkProps?.css,
];
+ const { closePortals } = useContext(EuiCollapsibleNavContext);
+ const onClick = useCallback(
+ (event: React.MouseEvent) => {
+ rest.onClick?.(event);
+ linkProps?.onClick?.(event as any);
+ if (!event.defaultPrevented) {
+ closePortals?.(event);
+ }
+ },
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ [rest.onClick, linkProps?.onClick, closePortals]
+ );
+
return isInteractive ? (
diff --git a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/index.ts b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/index.ts
index 3cfd0ef8d2a..71f7efe0600 100644
--- a/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/index.ts
+++ b/packages/eui/src/components/collapsible_nav_beta/collapsible_nav_item/index.ts
@@ -11,4 +11,7 @@ export type {
EuiCollapsibleNavSubItemProps,
} from './collapsible_nav_item';
-export { EuiCollapsibleNavItem } from './collapsible_nav_item';
+export {
+ EuiCollapsibleNavItem,
+ EuiCollapsibleNavSubItem,
+} from './collapsible_nav_item';
diff --git a/packages/eui/src/components/collapsible_nav_beta/context.ts b/packages/eui/src/components/collapsible_nav_beta/context.ts
index 2cde9af0955..7ae67a730a9 100644
--- a/packages/eui/src/components/collapsible_nav_beta/context.ts
+++ b/packages/eui/src/components/collapsible_nav_beta/context.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { createContext } from 'react';
+import { createContext, MouseEventHandler } from 'react';
import { _EuiFlyoutSide } from '../flyout/flyout';
@@ -15,6 +15,7 @@ type _EuiCollapsibleNavContext = {
isPush: boolean;
isOverlayOpen: boolean;
side: _EuiFlyoutSide;
+ closePortals?: MouseEventHandler;
};
export const EuiCollapsibleNavContext =