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
32 changes: 13 additions & 19 deletions frontend/src/components/app-layout/NavBar.test.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,31 @@
import { render, screen } from "@testing-library/react";
import { screen } from "@testing-library/react";
import { describe, it, expect } from "vitest";
import NavBar from "./NavBar";
import { renderWithProviders } from "../../tests/test-utils";

describe("NavBar", () => {
it("renders Working Groups link with correct URL", () => {
render(<NavBar />);
it("renders an explicit homepage link", () => {
renderWithProviders(<NavBar />);

const workingGroupsLink = screen.getByRole("link", {
name: /working groups/i,
const homeLink = screen.getByRole("link", {
name: /gpu mode home/i,
});

expect(workingGroupsLink).toBeInTheDocument();
expect(workingGroupsLink).toHaveAttribute("href", "/working-groups");
// Internal link should not have target="_blank" or rel="noopener"
expect(workingGroupsLink).not.toHaveAttribute("target", "_blank");
expect(workingGroupsLink).not.toHaveAttribute("rel", "noopener");
expect(homeLink).toHaveAttribute("href", "/home");
expect(homeLink).toHaveTextContent("Home");
});

it("renders all expected navigation links in correct order", () => {
render(<NavBar />);
renderWithProviders(<NavBar />);

const links = screen.getAllByRole("link");
const navigationLinks = links.filter((link) =>
["News", "Working Groups", "Events", "Resources", "Docs"].includes(
link.textContent || "",
),
["News", "Events", "Projects"].includes(link.textContent || ""),
);

expect(navigationLinks).toHaveLength(5);
expect(navigationLinks).toHaveLength(3);
expect(navigationLinks[0]).toHaveTextContent("News");
expect(navigationLinks[1]).toHaveTextContent("Working Groups");
expect(navigationLinks[2]).toHaveTextContent("Events");
expect(navigationLinks[3]).toHaveTextContent("Resources");
expect(navigationLinks[4]).toHaveTextContent("Docs");
expect(navigationLinks[1]).toHaveTextContent("Events");
expect(navigationLinks[2]).toHaveTextContent("Projects");
});
});
49 changes: 42 additions & 7 deletions frontend/src/components/app-layout/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward";
import LightModeIcon from "@mui/icons-material/LightMode";
import DarkModeIcon from "@mui/icons-material/DarkMode";
import SettingsBrightnessIcon from "@mui/icons-material/SettingsBrightness";
import HomeRoundedIcon from "@mui/icons-material/HomeRounded";
import { useTheme } from "@mui/material/styles";
import {
flexRowCenter,
Expand Down Expand Up @@ -60,15 +61,42 @@ export default function NavBar() {
];

const Brand = () => (
<Box sx={brandStyle}>
<Link href="/" underline="none" color="inherit">
<Box sx={{ ...flexRowCenter }}>
<Box
sx={{
...brandStyle,
position: { xs: "sticky", sm: "static" },
left: 0,
zIndex: 1,
bgcolor: "background.paper",
}}
>
<Link
href="/home"
aria-label="GPU MODE home"
underline="none"
color="inherit"
sx={{ display: "block" }}
>
<Box
sx={{
...flexRowCenter,
display: { xs: "flex", sm: "none" },
minHeight: 44,
px: 0.5,
fontSize: "1rem",
fontWeight: 600,
}}
>
<HomeRoundedIcon sx={{ fontSize: 22 }} />
Home
</Box>
<Box sx={{ display: { xs: "none", sm: "flex" } }}>
<Box
component="img"
src={logoSrc}
alt="GPU MODE"
alt=""
sx={{
height: { xs: 24, sm: 32 },
height: 32,
maxWidth: "100%",
}}
/>
Expand All @@ -80,12 +108,19 @@ export default function NavBar() {
return (
<AppBar position="fixed" sx={appBarStyle}>
<ConstrainedContainer>
<Toolbar sx={{ px: 0, gap: 2, overflowX: "auto" }}>
<Toolbar sx={{ px: 0, gap: { xs: 1, sm: 2 }, overflowX: "auto" }}>
{/* Left: Brand */}
<Brand />

{/* Middle: Links */}
<Box sx={{ ...flexRowCenterMediumGap, ml: 3, flexShrink: 0 }}>
<Box
sx={{
...flexRowCenterMediumGap,
gap: { xs: 2.5, sm: 5 },
ml: { xs: 0, sm: 3 },
flexShrink: 0,
}}
>
{links.map(({ label, href, external }) => (
<Link
key={label}
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/app-layout/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ export const brandStyle: SxProps<Theme> = {
...flexRowCenter,
...mediumText,
fontWeight: "bold",
ml: -2, // Negative left margin to reduce space from left edge
flexShrink: 0,
ml: { xs: 0, sm: -2 }, // Keep the mobile home control fully visible
mr: {
xs: 2, // margin on extra-small screens
xs: 1, // margin on extra-small screens
sm: 4, // margin on small screens
md: 8, // margin on medium screens
lg: 16, // margin on large screens
Expand Down
Loading