Skip to content

Commit

Permalink
Close popover when clicking links in collapsed state
Browse files Browse the repository at this point in the history
  • Loading branch information
sebelga committed Nov 14, 2024
1 parent 50e3c74 commit 6633ebe
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ export const Playground: Story = {
{ title: 'Dashboards', href: '#' },
{ title: 'Visualize library', href: '#' },
]),
{
title: 'Machine learning',
items: [
{ title: 'Anomaly detection', href: '#' },
{ title: 'Data frame analytics', href: '#' },
{
title: 'Sub group',
items: [
{ title: 'Sub item 1', href: '#' },
{ title: 'Sub item 2', href: '#' },
],
},
],
},
...renderGroup('Content', [
{ title: 'Indices', href: '#' },
{ title: 'Transforms', href: '#' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import {
EuiCollapsibleNavSubItem,
EuiCollapsibleNavItemProps,
EuiCollapsibleNavSubItemProps,
} from '../collapsible_nav_item';

import { EuiCollapsedNavButton } from './collapsed_nav_button';
Expand Down Expand Up @@ -48,6 +49,47 @@ export const EuiCollapsedNavPopover: FunctionComponent<
);
const closePopover = useCallback(() => setIsPopoverOpen(false), []);

const withOnClick = (
item: EuiCollapsibleNavSubItemProps
): EuiCollapsibleNavSubItemProps => {
if (item.renderItem) {
return item;
}

const { renderItem, href, linkProps, ...rest } = item;

const updatedItem: EuiCollapsibleNavSubItemProps = {
...rest,
};

if (href || linkProps) {
updatedItem.href = href;
updatedItem.linkProps = linkProps;
} else {
updatedItem.items = rest.items ? rest.items?.map(withOnClick) : undefined;
}

if (!updatedItem.items) {
// Only override the onClick if there are no sub-items (leaf node)
updatedItem.onClick = (e: React.MouseEvent<HTMLElement>) => {
if (rest.onClick) {
rest.onClick(e);
}

closePopover();

setTimeout(() => {
if (document.activeElement instanceof HTMLElement) {
// We don't want the tooltip to appear after closing the popover
document.activeElement.blur();
}
}, 10);
};
}

return updatedItem;
};

return (
<EuiPopover
closePopover={closePopover}
Expand Down Expand Up @@ -81,7 +123,11 @@ export const EuiCollapsedNavPopover: FunctionComponent<
</EuiPopoverTitle>
<div css={styles.euiCollapsedNavPopover__items}>
{items!.map((item, index) => (
<EuiCollapsibleNavSubItem key={index} {...item} />
<EuiCollapsibleNavSubItem
key={index}
closePopover={closePopover}
{...withOnClick(item)}
/>
))}
</div>
</EuiPopover>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,13 @@ export type EuiCollapsibleNavItemProps = _SharedEuiCollapsibleNavItemProps & {
>;

export type EuiCollapsibleNavCustomSubItem = {
renderItem: () => ReactNode;
renderItem: (options: {
/**
* When the side nav is collapsed, the menu appears in a EuiPopover. Use this handler to close the popover.
* If the handler is not defined it means that the side nav is not collapsed.
*/
closePopover?: () => void;
}) => ReactNode;
};

export type EuiCollapsibleNavSubItemProps = ExclusiveUnion<
Expand Down Expand Up @@ -226,12 +232,12 @@ export const EuiCollapsibleNavItemTitle: FunctionComponent<
* or they can simply be more links or accordions
*/
export const EuiCollapsibleNavSubItem: FunctionComponent<
EuiCollapsibleNavSubItemProps
> = ({ renderItem, className, ...props }) => {
EuiCollapsibleNavSubItemProps & { closePopover?: () => void }
> = ({ renderItem, className, closePopover, ...props }) => {
const classes = classNames('euiCollapsibleNavSubItem', className);

if (renderItem) {
return <>{renderItem()}</>;
return <>{renderItem({ closePopover })}</>;
}

return (
Expand Down

0 comments on commit 6633ebe

Please sign in to comment.