Skip to content

Commit

Permalink
Use a themeable image in footer
Browse files Browse the repository at this point in the history
  • Loading branch information
akademy authored Jan 8, 2025
1 parent a247957 commit b05ff08
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 26 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"scripts": {
"build": "tsc -b && rollup --config rollup.config.mjs",
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"lint:tsc": "pnpm tsc --noEmit",
"rollup": "rollup --config rollup.config.mjs",
"jest": "jest --config jest.config.js",
Expand Down
34 changes: 31 additions & 3 deletions src/components/Footer.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,47 @@ const meta: Meta<typeof Footer> = {
export default meta;
type Story = StoryObj<typeof meta>;

export const All: Story = {
args: {
logo: "theme",
copyright: "Company",
children: [
<FooterLinks key="footer-links">
<FooterLink href="#TheMoon" key="the-moon">
The Moon
</FooterLink>
<FooterLink href="#Phobos" key="phobos">
Phobos
</FooterLink>
<FooterLink href="#Ganymede" key="ganymede">
Ganymede
</FooterLink>
<FooterLink href="#Titan" key="titan">
Titan
</FooterLink>
</FooterLinks>,
],
},
};

export const LogoOnly: Story = {
args: {},
args: {
logo: "theme",
},
};

export const CopyrightOnly: Story = {
args: {
logo: "",
logo: null,
copyright: "Company",
},
};

export const CopyrightAndLogo: Story = {
args: { copyright: "Company" },
args: {
logo: "theme",
copyright: "Company",
},
};

export const WithOneLink: Story = {
Expand Down
41 changes: 29 additions & 12 deletions src/components/Footer.test.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
import { render, screen, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";

import dlsLogo from "../public/dls.svg";

import dlsLogo from "../public/generic/logo-short.svg";
import { Footer, FooterLink, FooterLinks } from "./Footer";
import { ImageColorSchemeSwitch } from "./ImageColorSchemeSwitch";
import { ThemeProvider } from "../themes/ThemeProvider";

jest.mock("./ImageColorSchemeSwitch");
// @ts-expect-error: doesn't find mockImplementation outside of testing.
ImageColorSchemeSwitch.mockImplementation(() => <img src="src" alt="alt" />);

describe("Footer", () => {
test("Should render logo only", async () => {
render(<Footer logo={dlsLogo} />);
test("Should render logo only", () => {
render(<Footer logo={{ src: dlsLogo, alt: "t" }} />);

await waitFor(() => {
expect(screen.getByRole("img")).toBeInTheDocument();
// No copyright text
expect(screen.queryByRole("paragraph")).not.toBeTruthy();
});
expect(screen.getByRole("img")).toBeInTheDocument();
// No copyright text
expect(screen.queryByRole("paragraph")).not.toBeInTheDocument();
});

test("Should render logo via theme", () => {
render(
<ThemeProvider>
<Footer logo="theme" />
</ThemeProvider>,
);

expect(screen.getByRole("img")).toBeInTheDocument();
});

test("Should render copyright only", async () => {
Expand All @@ -33,12 +47,15 @@ describe("Footer", () => {
test("Should render logo and copyright", async () => {
const copyrightText = "add text here";
const currentYear = new Date().getFullYear();
render(<Footer logo={dlsLogo} copyright={copyrightText} />);
render(
<Footer logo={{ src: dlsLogo, alt: "" }} copyright={copyrightText} />,
);

await waitFor(() => {
expect(screen.getByRole("img")).toBeInTheDocument();
expect(screen.queryByRole("paragraph")).toBeInTheDocument();
expect(screen.queryByRole("paragraph")?.textContent).toStrictEqual(
const paragraph = screen.getByRole("paragraph");
expect(paragraph).toBeInTheDocument();
expect(paragraph.textContent).toStrictEqual(
`Copyright © ${currentYear} ${copyrightText}`,
);
});
Expand Down
21 changes: 12 additions & 9 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { Link, LinkProps, Typography, useTheme } from "@mui/material";
import Grid from "@mui/material/Grid2";
import dlsLogo from "../public/logo-short.svg";

import React from "react";
import {
ImageColorSchemeSwitch,
ImageColorSchemeSwitchType,
} from "./ImageColorSchemeSwitch";

interface FooterLinksProps {
children: React.ReactElement<LinkProps> | React.ReactElement<LinkProps>[];
}

interface FooterProps extends React.HTMLProps<HTMLDivElement> {
/** Location/content of the logo */
logo?: string | null;
logo?: ImageColorSchemeSwitchType | "theme" | null;
copyright?: string | null;
children?: React.ReactElement | React.ReactElement[];
}
Expand Down Expand Up @@ -57,14 +61,13 @@ const FooterLink = ({ children, ...props }: LinkProps) => {
* Basic footer bar.
* Can be used with `FooterLinks` and `FooterLink` to display a list of links.
*/
const Footer = ({
logo = dlsLogo as string,
copyright,
children,
...props
}: FooterProps) => {
const Footer = ({ logo, copyright, children, ...props }: FooterProps) => {
const theme = useTheme();

if (logo === "theme") {
logo = theme.logos?.short;
}

return (
<footer
style={{
Expand Down Expand Up @@ -93,7 +96,7 @@ const Footer = ({
textAlign: "right",
}}
>
{logo ? <img alt="footer-logo" src={logo} /> : null}
{logo && <ImageColorSchemeSwitch image={logo} />}
{copyright ? (
<Typography
style={{
Expand Down
33 changes: 31 additions & 2 deletions src/components/Navbar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,33 @@ const meta: Meta<typeof Navbar> = {
export default meta;
type Story = StoryObj<typeof meta>;

export const Empty: Story = {
args: {},
export const All: Story = {
args: {
children: [
<NavLinks key="links">
<NavLink href="#Mercury" key="mercury">
Mercury
</NavLink>
<NavLink href="#Venus" key="venus">
Venus
</NavLink>
<NavLink href="#Earth" key="earth">
Earth
</NavLink>
<NavLink href="#Mars" key="mars">
Mars
</NavLink>
</NavLinks>,
<User
key="user"
onLogin={() => {}}
onLogout={() => {}}
user={{ name: "Name", fedid: "FedID" }}
color={"white"}
/>,
],
logo: "theme",
},
};

export const WithLogin: Story = {
Expand Down Expand Up @@ -133,3 +158,7 @@ export const CustomChildElement: Story = {
children: <Chip label="Hello, World" sx={{ backgroundColor: "#aaaaaa" }} />,
},
};

export const Empty: Story = {
args: {},
};
File renamed without changes
98 changes: 98 additions & 0 deletions src/public/generic/logo-short.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions src/themes/DiamondTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { BaseThemeOptions } from "./BaseTheme";

import logoImageDark from "../public/diamond/logo-dark.svg";
import logoImageLight from "../public/diamond/logo-light.svg";
import logoShort from "../public/diamond/logo-short.svg";

const dlsLogoBlue = "#202740";
const dlsLogoYellow = "#facf07";
Expand All @@ -17,6 +18,11 @@ const DiamondTheme: Theme = createTheme({
alt: "Diamond Source Logo",
width: "100",
},
short: {
src: logoShort,
alt: "Diamond Source Logo",
width: "65",
},
},
colorSchemes: {
// https://zenoo.github.io/mui-theme-creator/
Expand Down
5 changes: 5 additions & 0 deletions src/themes/GenericTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ const GenericTheme: Theme = createTheme({
alt: "Diamond Source Logo",
width: "100",
},
short: {
src: logoImageDark,
alt: "Diamond Source Logo",
width: "60",
},
},
});

Expand Down

0 comments on commit b05ff08

Please sign in to comment.