Skip to content

Commit d834231

Browse files
committed
Colour scheme switcher.
1 parent a1840b8 commit d834231

File tree

5 files changed

+119
-1
lines changed

5 files changed

+119
-1
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Meta, StoryObj } from "@storybook/react";
2+
import { ColourSchemeButton } from "./ColourSchemeButton";
3+
4+
5+
const meta: Meta<typeof ColourSchemeButton> = {
6+
title: "SciReactUI/Control/ColorSchemeButton",
7+
component: ColourSchemeButton,
8+
tags: ["autodocs"],
9+
parameters: {
10+
docs: {
11+
description: {
12+
component: 'Switch between dark and light modes.'
13+
},
14+
},
15+
},
16+
};
17+
18+
export default meta;
19+
type Story = StoryObj<typeof meta>;
20+
21+
export const LightSelected: Story = {
22+
args: {}
23+
};
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import "@testing-library/jest-dom";
2+
import { render, fireEvent } from "@testing-library/react";
3+
4+
import { ColourSchemeButton } from "./ColourSchemeButton";
5+
import {ColourSchemes} from "../utils/globals";
6+
7+
let mockSetColorScheme = jest.fn()
8+
jest.mock("@mui/material", () => {
9+
return {
10+
...jest.requireActual("@mui/material"),
11+
useColorScheme: jest.fn().mockReturnValue({
12+
colorScheme: jest.requireActual("../utils/globals").ColourSchemes.Dark,
13+
setColorScheme: (scheme : ColourSchemes) => mockSetColorScheme(scheme)
14+
})
15+
};
16+
})
17+
18+
describe("ColourSchemeButton", () => {
19+
20+
it("should render without errors", () => {
21+
render(<ColourSchemeButton />);
22+
});
23+
24+
it("should show dark icon and button", () => {
25+
const {getByTestId, getByRole} = render(<ColourSchemeButton />);
26+
27+
const button = getByRole("button")
28+
expect(button).toBeInTheDocument()
29+
30+
const icon = getByTestId("BedtimeIcon")
31+
expect(icon).toBeInTheDocument()
32+
});
33+
34+
it("should change colour scheme on click", () => {
35+
const {getByRole} = render(<ColourSchemeButton />);
36+
37+
const button = getByRole("button")
38+
fireEvent.click(button);
39+
40+
expect(mockSetColorScheme).toHaveBeenCalledWith(ColourSchemes.Light)
41+
});
42+
43+
it("should call local onclick when button clicked", () => {
44+
const mockOnClick = jest.fn();
45+
const {getByRole} = render(<ColourSchemeButton onClick={mockOnClick}/>);
46+
47+
const button = getByRole("button")
48+
fireEvent.click(button);
49+
50+
expect(mockOnClick).toHaveBeenCalled()
51+
});
52+
})
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import {useColorScheme, useTheme} from "@mui/material";
2+
import {IconButton, IconButtonProps} from "@mui/material";
3+
import {LightMode, Bedtime} from "@mui/icons-material";
4+
5+
import {ColourSchemes} from "../utils/globals";
6+
7+
const ColourSchemeButton = (props: IconButtonProps)=> {
8+
const theme = useTheme();
9+
const {colorScheme: colourScheme, setColorScheme: setColourScheme} = useColorScheme()
10+
11+
if( !colourScheme ) return undefined;
12+
13+
const isDark = () : boolean => colourScheme === ColourSchemes.Dark
14+
15+
return <IconButton
16+
sx={{
17+
height: 35,
18+
width: 35,
19+
borderRadius:"5px",
20+
backgroundColor:theme.palette.primary.light,
21+
color: theme.palette.primary.contrastText,
22+
"&:hover": {
23+
opacity: 0.8,
24+
backgroundImage: "",
25+
backgroundColor: isDark() ? "#111" : "skyblue",
26+
color: "yellow"
27+
},
28+
}}
29+
aria-label={`Colour scheme switcher: ${colourScheme}`}
30+
{...props}
31+
onClick={(event)=> {
32+
setColourScheme( isDark() ? ColourSchemes.Light : ColourSchemes.Dark )
33+
if( props.onClick ) props.onClick(event)
34+
}}
35+
>
36+
{ isDark() ? <Bedtime/> : <LightMode />}
37+
</IconButton>
38+
};
39+
40+
export type {IconButtonProps};
41+
export {ColourSchemeButton};

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
// components
22
export * from "./components/Breadcrumbs";
3-
export * from "./components/Navbar";
3+
export * from "./components/ColourSchemeButton";
44
export * from "./components/Footer";
5+
export * from "./components/Navbar";
56
export * from "./components/User";
67
export * from "./components/VisitInput";
78
export * from "./components/ImageColorSchemeSwitch";

src/utils/globals.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export enum ColourSchemes { Light="light", Dark="dark" }

0 commit comments

Comments
 (0)