diff --git a/packages/lib/src/base-menu/GroupItem.tsx b/packages/lib/src/base-menu/GroupItem.tsx
index 7817dfd214..177e1dab38 100644
--- a/packages/lib/src/base-menu/GroupItem.tsx
+++ b/packages/lib/src/base-menu/GroupItem.tsx
@@ -36,14 +36,18 @@ const GroupItem = ({ items, ...props }: GroupItemProps) => {
aria-controls={isOpen ? groupMenuId : undefined}
aria-expanded={isOpen ? true : undefined}
collapseIcon={isOpen ? : }
- onClick={() => toggleOpen()}
+ onClick={() => {
+ toggleOpen();
+ }}
selected={groupSelected && !isOpen}
{...props}
/>
{portalContainer && (
-
+
{
@@ -107,7 +111,9 @@ const GroupItem = ({ items, ...props }: GroupItemProps) => {
aria-expanded={isOpen ? true : undefined}
aria-pressed={groupSelected && !isOpen}
collapseIcon={isOpen ? : }
- onClick={() => toggleOpen()}
+ onClick={() => {
+ toggleOpen();
+ }}
selected={groupSelected && !isOpen}
{...props}
/>
diff --git a/packages/lib/src/base-menu/SingleItem.tsx b/packages/lib/src/base-menu/SingleItem.tsx
index 71606d85dd..11d57bd384 100644
--- a/packages/lib/src/base-menu/SingleItem.tsx
+++ b/packages/lib/src/base-menu/SingleItem.tsx
@@ -4,11 +4,14 @@ import { SingleItemProps } from "./types";
import BaseMenuContext from "./BaseMenuContext";
export default function SingleItem({ id, onSelect, selected = false, ...props }: SingleItemProps) {
- const { selectedItemId, setSelectedItemId } = useContext(BaseMenuContext) ?? {};
+ const { selectedItemId, setSelectedItemId, hasPopOver, closePopOver, onSelectItem } =
+ useContext(BaseMenuContext) ?? {};
const handleClick = () => {
setSelectedItemId?.(id);
onSelect?.();
+ if (!hasPopOver) closePopOver?.();
+ onSelectItem?.();
};
useEffect(() => {
diff --git a/packages/lib/src/base-menu/types.ts b/packages/lib/src/base-menu/types.ts
index adf2ea4fe8..20fdb1545a 100644
--- a/packages/lib/src/base-menu/types.ts
+++ b/packages/lib/src/base-menu/types.ts
@@ -45,6 +45,11 @@ type Props = {
* If true the menu will be displayed horizontally.
*/
isHorizontal?: boolean;
+ /**
+ * Function that will be called when an option is clicked.
+ * This is used to notify that an item has been selected to close any visible menu that is not managed by the navigation tree.
+ */
+ onSelectItem?: () => void;
};
type ItemWithId = Item & { id: number };
@@ -94,6 +99,8 @@ type BaseMenuContextProps = {
displayControlsAfter?: boolean;
hasPopOver?: boolean;
isHorizontal?: boolean;
+ onSelectItem?: () => void;
+ closePopOver?: () => void;
};
export type {
diff --git a/packages/lib/src/base-menu/useGroupItem.ts b/packages/lib/src/base-menu/useGroupItem.ts
index c24123ee1d..96f11608bd 100644
--- a/packages/lib/src/base-menu/useGroupItem.ts
+++ b/packages/lib/src/base-menu/useGroupItem.ts
@@ -14,7 +14,9 @@ export const useGroupItem = (items: GroupItemProps["items"], context: BaseMenuCo
const groupSelected = useMemo(() => isGroupSelected(items, selectedItemId), [items, selectedItemId]);
const [isOpen, setIsOpen] = useState(hasPopOver ? false : (defaultOpen ?? (groupSelected && selectedItemId === -1)));
- const toggleOpen = () => setIsOpen((prev) => !prev);
+ const toggleOpen = () => {
+ setIsOpen((prev) => !prev);
+ };
return {
groupMenuId,
@@ -23,5 +25,6 @@ export const useGroupItem = (items: GroupItemProps["items"], context: BaseMenuCo
toggleOpen,
hasPopOver: context.hasPopOver,
isHorizontal: context.isHorizontal,
+ onSelectItem: context.onSelectItem,
};
};
diff --git a/packages/lib/src/header/Header.test.tsx b/packages/lib/src/header/Header.test.tsx
index 0b4367cbf6..760a591d6f 100644
--- a/packages/lib/src/header/Header.test.tsx
+++ b/packages/lib/src/header/Header.test.tsx
@@ -6,6 +6,30 @@ import { Item, GroupItem } from "../base-menu/types";
describe("Header component tests", () => {
const mockMatchMedia = jest.fn();
+ const items = [
+ {
+ label: "Grouped Item 1",
+ icon: "favorite",
+ items: [
+ { label: "Item 1", icon: "person", selected: true },
+ {
+ label: "Grouped Item 2",
+ items: [
+ {
+ label: "Item 2",
+ icon: "bookmark",
+ },
+ { label: "Selected Item 3" },
+ ],
+ },
+ ],
+ },
+ { label: "Item 4", icon: "key" },
+ { label: "Item 5", icon: "person" },
+ { label: "Grouped Item 6", items: [{ label: "Item 7", icon: "person" }, { label: "Item 8" }] },
+ { label: "Item 9" },
+ ];
+
beforeAll(() => {
Object.defineProperty(window, "matchMedia", {
writable: true,
@@ -95,4 +119,13 @@ describe("Header component tests", () => {
const cancelButton = screen.queryByRole("button", { name: /cancel/i });
expect(cancelButton).not.toBeInTheDocument();
});
+
+ test("navigation group items closes whenever an item is clicked", () => {
+ render();
+ const itemGroup6 = screen.getByText("Grouped Item 6");
+ fireEvent.click(itemGroup6);
+ const item7 = screen.getByText("Item 7");
+ fireEvent.click(item7);
+ expect(item7).not.toBeInTheDocument();
+ });
});
diff --git a/packages/lib/src/header/Header.tsx b/packages/lib/src/header/Header.tsx
index cdd4089c60..5bfbeb447c 100644
--- a/packages/lib/src/header/Header.tsx
+++ b/packages/lib/src/header/Header.tsx
@@ -272,6 +272,7 @@ const DxcHeader = ({
displayGroupLines={false}
displayBorder={false}
displayControlsAfter
+ onSelectItem={() => toggleMenu()}
/>
{responsiveBottomContent && (
<>
diff --git a/packages/lib/src/navigation-tree/NavigationTree.tsx b/packages/lib/src/navigation-tree/NavigationTree.tsx
index f47568d38a..9691dee40e 100644
--- a/packages/lib/src/navigation-tree/NavigationTree.tsx
+++ b/packages/lib/src/navigation-tree/NavigationTree.tsx
@@ -34,6 +34,7 @@ export default function DxcNavigationTree({
displayControlsAfter = false,
hasPopOver = false,
isHorizontal = false,
+ onSelectItem,
}: NavigationTreePropsType) {
const [firstUpdate, setFirstUpdate] = useState(true);
const [selectedItemId, setSelectedItemId] = useState(-1);
@@ -48,8 +49,9 @@ export default function DxcNavigationTree({
displayControlsAfter,
hasPopOver,
isHorizontal,
+ onSelectItem,
}),
- [selectedItemId, setSelectedItemId, displayGroupLines, displayControlsAfter, hasPopOver, isHorizontal]
+ [selectedItemId, setSelectedItemId, displayGroupLines, displayControlsAfter, hasPopOver, isHorizontal, onSelectItem]
);
useLayoutEffect(() => {