Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions packages/lib/src/base-menu/GroupItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,18 @@ const GroupItem = ({ items, ...props }: GroupItemProps) => {
aria-controls={isOpen ? groupMenuId : undefined}
aria-expanded={isOpen ? true : undefined}
collapseIcon={isOpen ? <DxcIcon icon="filled_expand_less" /> : <DxcIcon icon="filled_expand_more" />}
onClick={() => toggleOpen()}
onClick={() => {
toggleOpen();
}}
selected={groupSelected && !isOpen}
{...props}
/>
</Popover.Trigger>
{portalContainer && (
<Popover.Portal container={portalContainer}>
<BaseMenuContext.Provider value={{ ...contextValue, displayGroupLines: false, hasPopOver: false }}>
<BaseMenuContext.Provider
value={{ ...contextValue, displayGroupLines: false, hasPopOver: false, closePopOver: toggleOpen }}
>
<Popover.Content
aria-label="Group details"
onKeyDown={(event) => {
Expand Down Expand Up @@ -107,7 +111,9 @@ const GroupItem = ({ items, ...props }: GroupItemProps) => {
aria-expanded={isOpen ? true : undefined}
aria-pressed={groupSelected && !isOpen}
collapseIcon={isOpen ? <DxcIcon icon="filled_expand_less" /> : <DxcIcon icon="filled_expand_more" />}
onClick={() => toggleOpen()}
onClick={() => {
toggleOpen();
}}
selected={groupSelected && !isOpen}
{...props}
/>
Expand Down
5 changes: 4 additions & 1 deletion packages/lib/src/base-menu/SingleItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand Down
7 changes: 7 additions & 0 deletions packages/lib/src/base-menu/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -94,6 +99,8 @@ type BaseMenuContextProps = {
displayControlsAfter?: boolean;
hasPopOver?: boolean;
isHorizontal?: boolean;
onSelectItem?: () => void;
closePopOver?: () => void;
};

export type {
Expand Down
5 changes: 4 additions & 1 deletion packages/lib/src/base-menu/useGroupItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -23,5 +25,6 @@ export const useGroupItem = (items: GroupItemProps["items"], context: BaseMenuCo
toggleOpen,
hasPopOver: context.hasPopOver,
isHorizontal: context.isHorizontal,
onSelectItem: context.onSelectItem,
};
};
33 changes: 33 additions & 0 deletions packages/lib/src/header/Header.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(<DxcHeader navItems={items} />);
const itemGroup6 = screen.getByText("Grouped Item 6");
fireEvent.click(itemGroup6);
const item7 = screen.getByText("Item 7");
fireEvent.click(item7);
expect(item7).not.toBeInTheDocument();
});
});
1 change: 1 addition & 0 deletions packages/lib/src/header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ const DxcHeader = ({
displayGroupLines={false}
displayBorder={false}
displayControlsAfter
onSelectItem={() => toggleMenu()}
/>
{responsiveBottomContent && (
<>
Expand Down
4 changes: 3 additions & 1 deletion packages/lib/src/navigation-tree/NavigationTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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(() => {
Expand Down
Loading