Skip to content

Commit

Permalink
fix(nav): Nav collapses when links are clicked on mobile MAASENG-2384 (
Browse files Browse the repository at this point in the history
…#5345)

- Navigation will now collapse automatically when a link is clicked (on mobile)
- Added a cypress test to ensure this functionality
  • Loading branch information
ndv99 committed Mar 13, 2024
1 parent 77f7792 commit 4458985
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 3 deletions.
12 changes: 12 additions & 0 deletions cypress/e2e/with-users/base/navigation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ context("Navigation - admin - collapse", () => {
.within(() => cy.findByRole("button", { name: /close menu/i }).click());
cy.getMainNavigation().should("not.be.visible");
});

it("automatically closes the menu on mobile when a link is clicked", () => {
cy.viewport("iphone-8");
cy.getMainNavigation().should("not.be.visible");
cy.findByRole("banner", { name: "navigation" }).within(() =>
cy.findByRole("button", { name: "Menu" }).click()
);
cy.getMainNavigation()
.should("be.visible")
.within(() => cy.findByRole("link", { name: /devices/i }).click());
cy.getMainNavigation().should("not.be.visible");
});
});

context("Navigation - admin", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,26 @@ import { Navigation } from "@canonical/maas-react-components";
import classNames from "classnames";
import { Link } from "react-router-dom-v5-compat";

import type { SideNavigationProps } from "../AppSideNavigation";
import type { NavItem } from "../types";
import { isSelected } from "../utils";

import { useId } from "@/app/base/hooks/base";
import { MOBILE_VIEW_MAX_WIDTH } from "@/app/constants";

type Props = {
navLink: NavItem;
icon?: string | ReactNode;
path: string;
setIsCollapsed: SideNavigationProps["setIsCollapsed"];
};

export const AppSideNavItem = ({ navLink, icon, path }: Props): JSX.Element => {
export const AppSideNavItem = ({
navLink,
icon,
path,
setIsCollapsed,
}: Props): JSX.Element => {
const id = useId();
return (
<Navigation.Item
Expand All @@ -30,6 +38,10 @@ export const AppSideNavItem = ({ navLink, icon, path }: Props): JSX.Element => {
// removing the focus from the link element after click
// this allows the side navigation to collapse on mouseleave
e.currentTarget.blur();

if (window.innerWidth < MOBILE_VIEW_MAX_WIDTH) {
setIsCollapsed(true);
}
}}
to={navLink.url}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Navigation } from "@canonical/maas-react-components";
import { Button, Icon } from "@canonical/react-components";

import AppSideNavItem from "../AppSideNavItem";
import type { SideNavigationProps } from "../AppSideNavigation";
import type { NavGroup } from "../types";
import { isSelected } from "../utils";

Expand All @@ -18,6 +19,7 @@ type Props = {
isAuthenticated: boolean;
logout: () => void;
path: string;
setIsCollapsed: SideNavigationProps["setIsCollapsed"];
showLinks: boolean;
vaultIncomplete: boolean;
};
Expand All @@ -27,9 +29,10 @@ const AppSideNavItemGroup = ({
isAdmin,
vaultIncomplete,
path,
setIsCollapsed,
}: { group: NavGroup } & Pick<
Props,
"isAdmin" | "vaultIncomplete" | "path"
"isAdmin" | "vaultIncomplete" | "path" | "setIsCollapsed"
>) => {
const id = useId();
const hasActiveChild = useMemo(() => {
Expand Down Expand Up @@ -67,6 +70,7 @@ const AppSideNavItemGroup = ({
key={navLink.label}
navLink={navLink}
path={path}
setIsCollapsed={setIsCollapsed}
/>
);
} else return null;
Expand All @@ -84,6 +88,7 @@ export const AppSideNavItems = ({
isAuthenticated,
logout,
path,
setIsCollapsed,
showLinks,
vaultIncomplete,
}: Props): JSX.Element => {
Expand All @@ -97,6 +102,7 @@ export const AppSideNavItems = ({
isAdmin={isAdmin}
key={`${i}-${group.groupTitle}`}
path={path}
setIsCollapsed={setIsCollapsed}
vaultIncomplete={vaultIncomplete}
/>
))}
Expand All @@ -111,6 +117,7 @@ export const AppSideNavItems = ({
icon="settings"
navLink={{ label: "Settings", url: urls.settings.index }}
path={path}
setIsCollapsed={setIsCollapsed}
/>
</>
</ul>
Expand All @@ -123,6 +130,7 @@ export const AppSideNavItems = ({
url: urls.preferences.index,
}}
path={path}
setIsCollapsed={setIsCollapsed}
/>

<ul className="p-side-navigation__list">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import podSelectors from "@/app/store/pod/selectors";
import type { RootState } from "@/app/store/root/types";
import { actions as statusActions } from "@/app/store/status";

type SideNavigationProps = {
export type SideNavigationProps = {
authUser: ReturnType<typeof authSelectors.get>;
filteredGroups: typeof navGroups;
isAdmin: boolean;
Expand Down Expand Up @@ -96,6 +96,7 @@ export const AppSideNavigation = ({
isAuthenticated={isAuthenticated}
logout={logout}
path={path}
setIsCollapsed={setIsCollapsed}
showLinks={showLinks}
vaultIncomplete={vaultIncomplete}
/>
Expand Down
1 change: 1 addition & 0 deletions src/app/constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export const MAAS_UI_ID = "maas-ui";
export const MOBILE_VIEW_MAX_WIDTH = 620;

0 comments on commit 4458985

Please sign in to comment.