Skip to content

Commit cd73eb5

Browse files
authored
Allow props to change individual styles without overriding *all* defaults (#58)
* Allow props to change individual styles without overriding *all* the styles.
1 parent 92c232d commit cd73eb5

File tree

6 files changed

+93
-36
lines changed

6 files changed

+93
-36
lines changed

changelog.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
SciReactUI Changelog
22
====================
33

4+
5+
[v0.1.1] - 2025-?-?
6+
--------------------
7+
8+
### Added
9+
-
10+
11+
### Fixed
12+
- Styles added to Navbar and Footer incorrectly remove built in styles.
13+
14+
### Changed
15+
-
16+
417
[v0.1.0] - 2025-04-10
518
---------------------
619

@@ -56,7 +69,7 @@ SciReactUI Changelog
5669
- Generic
5770

5871

59-
[0.0.0] - 2024-06-04
72+
[v0.0.0] - 2024-06-04
6073
--------------------
6174

6275
### Added

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@diamondlightsource/sci-react-ui",
3-
"version": "0.1.0",
3+
"version": "0.1.1alpha",
44
"description": "A theme and component library to make websites at scientific institutions simple to create.",
55
"author": "Diamond Light Source",
66
"license": "ISC",

src/components/Footer.test.tsx

+25-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,29 @@ jest.mock("./ImageColorSchemeSwitch");
1010
// @ts-expect-error: doesn't find mockImplementation outside of testing.
1111
ImageColorSchemeSwitch.mockImplementation(() => <img src="src" alt="alt" />);
1212

13-
describe("Footer", () => {
13+
describe("Footer logo and copyright", () => {
14+
test("Should render", async () => {
15+
renderWithProviders(<Footer />);
16+
expect(await screen.findByRole("contentinfo")).toBeInTheDocument();
17+
});
18+
19+
test("Should renders correctly with styles", async () => {
20+
const borderStyle = "1px solid orange";
21+
renderWithProviders(<Footer style={{ border: borderStyle }} />);
22+
23+
const footerComputedStyle = window.getComputedStyle(
24+
await screen.findByRole("contentinfo"),
25+
);
26+
27+
// check new style is set
28+
expect(footerComputedStyle.border).toBe(borderStyle);
29+
30+
// Check default values are still set
31+
expect(footerComputedStyle.minHeight).toBe("50px");
32+
});
33+
});
34+
35+
describe("Footer logo and copyright", () => {
1436
test("Should render logo only", () => {
1537
renderWithProviders(<Footer logo={{ src: dlsLogo, alt: "t" }} />);
1638

@@ -56,7 +78,9 @@ describe("Footer", () => {
5678
);
5779
});
5880
});
81+
});
5982

83+
describe("Footer Links", () => {
6084
test("Should render with one link", async () => {
6185
const lineOneText = "Link one";
6286
const linkOneName = "link-one-href";

src/components/Footer.tsx

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import {
2+
Box,
3+
BoxProps,
4+
Grid2 as Grid,
25
Link,
36
LinkProps,
7+
styled,
48
Typography,
5-
Grid2 as Grid,
69
useTheme,
710
} from "@mui/material";
811

@@ -16,11 +19,9 @@ interface FooterLinksProps extends React.HTMLProps<HTMLDivElement> {
1619
children: React.ReactElement<LinkProps> | React.ReactElement<LinkProps>[];
1720
}
1821

19-
interface FooterProps extends React.HTMLProps<HTMLDivElement> {
20-
/** Location/content of the logo */
22+
interface FooterProps extends BoxProps, React.PropsWithChildren {
2123
logo?: ImageColorSchemeSwitchType | "theme" | null;
2224
copyright?: string | null;
23-
children?: React.ReactElement | React.ReactElement[];
2425
}
2526

2627
const FooterLinks = ({ children, ...props }: FooterLinksProps) => {
@@ -67,6 +68,13 @@ const FooterLink = ({ children, ...props }: LinkProps) => {
6768
);
6869
};
6970

71+
const BoxStyled = styled(Box)<BoxProps>(({ theme }) => ({
72+
bottom: 0,
73+
marginTop: "auto",
74+
minHeight: "50px",
75+
backgroundColor: theme.vars.palette.primary.light,
76+
}));
77+
7078
/*
7179
* Basic footer bar.
7280
* Can be used with `FooterLinks` and `FooterLink` to display a list of links.
@@ -79,15 +87,7 @@ const Footer = ({ logo, copyright, children, ...props }: FooterProps) => {
7987
}
8088

8189
return (
82-
<footer
83-
style={{
84-
bottom: 0,
85-
marginTop: "auto",
86-
minHeight: 50,
87-
backgroundColor: theme.vars.palette.primary.light,
88-
}}
89-
{...props}
90-
>
90+
<BoxStyled role="contentinfo" {...props}>
9191
<Grid container>
9292
<Grid
9393
size={logo || copyright ? { xs: 6, md: 8 } : { xs: 12, md: 12 }}
@@ -130,7 +130,7 @@ const Footer = ({ logo, copyright, children, ...props }: FooterProps) => {
130130
</Grid>
131131
)}
132132
</Grid>
133-
</footer>
133+
</BoxStyled>
134134
);
135135
};
136136

src/components/Navbar.test.tsx

+22
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,28 @@ import "@testing-library/jest-dom";
44
import { renderWithProviders } from "../__test-utils__/helpers";
55

66
describe("Navbar", () => {
7+
it("should render", async () => {
8+
renderWithProviders(<Navbar />);
9+
expect(await screen.findByRole("banner")).toBeInTheDocument();
10+
});
11+
12+
it("should render with styles", async () => {
13+
const borderStyle = "1px solid orange";
14+
renderWithProviders(<Navbar style={{ border: borderStyle }} />);
15+
16+
const headerComputedStyle = window.getComputedStyle(
17+
await screen.findByRole("banner"),
18+
);
19+
20+
// check new style is set
21+
expect(headerComputedStyle.border).toBe(borderStyle);
22+
23+
// Check default values are still set
24+
expect(headerComputedStyle.height).toBe("50px");
25+
});
26+
});
27+
28+
describe("Navbar Logo", () => {
729
it("should not display logo if null", () => {
830
global.innerWidth = 600;
931
renderWithProviders(<Navbar logo={null} />);

src/components/Navbar.tsx

+17-19
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import {
44
BoxProps,
55
Container,
66
Drawer,
7-
LinkProps,
87
Link,
8+
LinkProps,
99
IconButton,
1010
Stack,
11+
styled,
1112
useTheme,
1213
} from "@mui/material";
1314
import { MdMenu, MdClose } from "react-icons/md";
@@ -22,10 +23,8 @@ interface NavLinksProps {
2223
children: React.ReactElement<LinkProps> | React.ReactElement<LinkProps>[];
2324
}
2425

25-
interface NavbarProps extends BoxProps {
26-
/** Location/content of the logo */
26+
interface NavbarProps extends BoxProps, React.PropsWithChildren {
2727
logo?: ImageColorSchemeSwitchType | "theme" | null;
28-
children?: React.ReactElement | React.ReactElement[];
2928
}
3029

3130
const NavLink = ({ children, ...props }: LinkProps) => {
@@ -112,6 +111,18 @@ const NavLinks = ({ children }: NavLinksProps) => {
112111
);
113112
};
114113

114+
const BoxStyled = styled(Box)<BoxProps>(({ theme }) => ({
115+
top: 0,
116+
zIndex: 1,
117+
width: "100%",
118+
height: "50px",
119+
display: "flex",
120+
alignItems: "center",
121+
justifyContent: "space-between",
122+
borderRadius: 0,
123+
backgroundColor: theme.vars.palette.primary.main,
124+
}));
125+
115126
/**
116127
* Basic navigation bar. Can be used with `NavLinks` and `NavLink` to display a responsive list of links.
117128
*/
@@ -123,20 +134,7 @@ const Navbar = ({ children, logo, ...props }: NavbarProps) => {
123134
}
124135

125136
return (
126-
<Box
127-
top="0"
128-
zIndex={1}
129-
width="100%"
130-
height="50px"
131-
sx={{
132-
display: "flex",
133-
alignItems: "center",
134-
justifyContent: "space-between",
135-
borderRadius: 0,
136-
backgroundColor: theme.vars.palette.primary.main,
137-
}}
138-
{...props}
139-
>
137+
<BoxStyled role="banner" {...props}>
140138
<Container maxWidth="lg" sx={{ height: "100%" }}>
141139
<Stack
142140
direction="row"
@@ -159,7 +157,7 @@ const Navbar = ({ children, logo, ...props }: NavbarProps) => {
159157
{children}
160158
</Stack>
161159
</Container>
162-
</Box>
160+
</BoxStyled>
163161
);
164162
};
165163

0 commit comments

Comments
 (0)